android invoke 参数,android 使用反射獲取MediaPlayer的Invoke方法
最近有需求需要使用MediaPlayer的invoke接口去實現某些功能, 但是invoke接口是隱藏的, 沒有在sdk中開放出來. 所以使用反射的方法來獲取invoke接口, 但在實現的過程中出現一些問題, 在這里記錄一下.
1.使用反射的方式獲取隱藏的接口if (mMediaPlayer != null) {
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
request.writeInt(200);
Class> cls = mMediaPlayer.getClass();
Method method = cls.getDeclaredMethod("invoke", Parcel.class, Parcel.class);
method.setAccessible(true); //如果隱藏接口是public的, 這句可以不要
method.invoke(mMediaPlayer, request, reply);
int result = reply.readInt();
if (0 == result) {
return false;
} else if (1 == result) {
return true;
}
} catch (Exception e) {
e.getCause().printStackTrace();
} finally {
request.recycle();
reply.recycle();
}
}
反射的調用步驟:
(1) 獲取相關類的class
Class cls = mMediaPlayer.getClass();
或者通過包名獲取:
Class cls = Class.forName (“android.media.MediaPlayer”);
(2) 通過方法名獲得方法接口, 如果方法有參數, 需要將參數的class傳入
Method method = cls.getDeclaredMethod(“invoke”, Parcel.class, Parcel.class);
(3) 通過Method的invoke接口來實現方法的調用, 這時候需要傳參, 將參數傳入:
method.invoke(mMediaPlayer, request, reply);
2.出現的問題
當通過這種方式調用后會發現無效, 並且會打印下面的error信息:01-01 08:31:42.270 W/System.err( 1475): java.lang.reflect.InvocationTargetException
01-01 08:31:42.270 W/System.err( 1475): at java.lang.reflect.Method.invokeNative(Native Method)
01-01 08:31:42.270 W/System.err( 1475): at java.lang.reflect.Method.invoke(Method.java:511)
這個問題搞了好久, 反射調用的方法應該沒什么問題, 錯誤應該是其他的, 仔細看log發現有下列信息:01-01 08:31:42.269 E/Parcel ( 3212): Reading a NULL string not supported here.
我沒有傳入任何string下去, 卻報出這個error, 應該是需要再出入一個string下去.
這個時候查看MediaPlayer的源碼, 看到selectOrDeselectTrack等方法內部也是調用的invoke接口:private void selectOrDeselectTrack(int index, boolean select)
throws IllegalStateException {
Parcel request = Parcel.obtain();
Parcel reply = Parcel.obtain();
try {
request.writeInterfaceToken(IMEDIA_PLAYER);
request.writeInt(select ? INVOKE_ID_SELECT_TRACK
: INVOKE_ID_DESELECT_TRACK);
request.writeInt(index);
invoke(request, reply);
} finally {
request.recycle();
reply.recycle();
}
}
這里面與我寫的調用invoke接口多了一句:request.writeInterfaceToken(IMEDIA_PLAYER);
IMEDIA_PLAYER的值為:private final static String IMEDIA_PLAYER = "android.media.IMediaPlayer";
當我將這句加上測試后, 果然沒問題了, 調用成功. 這句代碼的意思是標識遠程服務的名稱. 不然不知道去啟動哪個服務來操作.
其實MediaPlayer中有提供方法來獲取Parcel對象, 但是此方法也是隱藏的:public Parcel newRequest() {
Parcel parcel = Parcel.obtain();
parcel.writeInterfaceToken(IMEDIA_PLAYER);
return parcel;
}
這個方法的內部也是調用了writeInterfaceToken接口.
3.其他
如果可以查看源碼, 其實每個方法的使用源碼中都有對應的test例子, 例如現在說的invoke方法, 在源碼中有 MediaPlayerInvokeTest.java, 這里面介紹了如何使用invoke接口, 下面是這個類的內容:// Tests for the invoke method in the MediaPlayer.
public class MediaPlayerInvokeTest extends
ActivityInstrumentationTestCase2 {
private static final String TAG = "MediaPlayerInvokeTest";
private MediaPlayer mPlayer;
private Random rnd;
public MediaPlayerInvokeTest() {
super("com.android.mediaframeworktest", MediaFrameworkTest.class);
rnd = new Random(Calendar.getInstance().getTimeInMillis());
}
@Override
protected void setUp() throws Exception {
super.setUp();
mPlayer = new MediaPlayer();
}
@Override
protected void tearDown() throws Exception {
mPlayer.release();
super.tearDown();
}
// Generate a random number, sends it to the ping test player.
@Suppress
@MediumTest
public void testPing() throws Exception {
mPlayer.setDataSource("test:invoke_mock_media_player.so?url=ping");
Parcel request = mPlayer.newRequest();
Parcel reply = Parcel.obtain();
int val = rnd.nextInt();
request.writeInt(val);
mPlayer.invoke(request, reply);
assertEquals(val, reply.readInt());
}
}
這次的收獲就是要學會善於查看android源碼.
android invoke 参数,android 使用反射獲取MediaPlayer的Invoke方法相关推荐
- android百度地图获取定位信息吗,android使用百度地圖定位(獲取當前經緯度和地址信息)...
首先,當然是把需要用到的包導入到工程項目中.(沒有包的自己去百度API官網下載) 把 baidumapapi_v3_0_0.jar 和 locSDK_4.2.jar復制粘貼到項目的libs目錄下, 然 ...
- android onpagescrolled 参数,Android
8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 背景 ViewPager 在应用中使用较为广泛,诸如页面轮播图,App引导页,大图预览等.其中指示器页比较重要 它用于提 ...
- android datepicker 参数,android常用组件之DatePicker和TimePicker
在android中,DatePicker组件和TimePicker组件分别是日期选择器和时间选择器. 该实例中,当点击日期选择器按钮后,弹出日期选择框,用户选择日期后andoid会将日期显示到Text ...
- android 多类型参数,Android的数据绑定-类型参数T具有不兼容的上限:ViewDataBinding和MainActivity...
我正在使用Android Studio 2.0 Preview 4.我正在使用Android SDK工具25 rc1. 无论我清理/重建项目多少次,此错误仍然存在. File-> Invalid ...
- Android平台使用-谷歌广告联盟AdMob-赚取收益的编程方法
谷歌广告联盟AdMob是什么 谷歌广告联盟AdMob是使用在Android.IOS平台的广告SDK. 常见的广告形式 横幅广告 插页广告 视频广告 横幅广告 gradle依赖 dependencies ...
- android sqlite 参数,Android SQLite3命令详解教程
SQLite3可以让我们手动的对SQLite数据库进行管理.一共有2个sqlite3,一个在电脑上,它位于 android-sdk-windows\tools\sqlite3.exe,用于电脑上SQL ...
- android getevent参数,android getevent、sendevent、input keyevent 使用说明
设备节点: dev 字符设备节点: shell@android:/dev/input $ ll crw-rw---- root input 13, 64 2013-11-28 17:23 event0 ...
- android settext 参数,Android TextView.setTextColor()的参数设置方式
摘要:Android TextView.setTextColor()的参数设置方式 查了下资料发现setTextColor()的参数应该写成以下的这种形式: setTextColor(0xFF0000 ...
- android onlescan 参数,Android BLE:从iOS外设广告时,在onLeScan()回调中检索服务UUID
我正在使用Nexus 4(4.4 kitkat)作为中央和iPad作为外设.外围设备有广告服务.广告包有一些数据(22字节)的服务UUID.当我尝试从 Android扫描外围设备时,iPad外围设备被 ...
最新文章
- 命名实体识别学习笔记——使用Ltp
- 使用Apple的感受
- 搭建属于自己的技术博客
- Ubuntu作为服务器其tomcat被远程访问问题
- 【AI视野·今日CV 计算机视觉论文速览 第197期】Thu, 13 May 2021
- python十个评委打分_八个评委打分,通过筛选确定最佳评委和最差评委。
- (68)FPGA面试题-使用不同的代码实现2:1 MUX ?使用assign语句
- Composite UI Application Block(CAB)
- python,web框架说明
- 基于java的药品管理系统_基于Java药品管理系统
- Unity常见问题(二)数组索引越界
- WPS Word添加或删除页面上/下方的横线
- 【强化学习】Policy Gradient(策略梯度)算法详解
- 和黄医药宣布获霸菱亚洲投资基金1亿美元股权投资
- React-滑条组件使用
- C++调用Lua出现 unproteted error in call to Lua API错误的发现过程与解决方法
- vue+element弹窗可拖拽拉伸和弹窗内table高度自适应
- requests库爬取百度首页
- python对参数二值化处理_OpenCV自适应阀值二值化表格检测方法(python版)
- 操作系统——文件分配和空间管理