首页 > 编程知识 正文

通俗理解java反射,android反射调用其他app

时间:2023-05-03 19:40:14 阅读:10915 作者:1403

最近,需要使用MediaPlayer的invoke接口实现某些功能,但invoke接口是隐藏的,在sdk中不开放。 因此,用反射的方法获取invoke接口,但在实现过程中出现了一些问题,在此记录。

1 .使用反射获取隐藏的接口if (媒体播放器!=空) {

Parcel request=Parcel.obtain (;

Parcel reply=Parcel.obtain (;

try {

request.writeint(200;

Class cls=mMediaPlayer.getClass (;

方法方法=cls.getdeclaredmethod (' invoke ',Parcel.class,Parcel.class );

method.set accessible (真; //如果隐藏接口是公共接口,则可以放弃此语句

method.invoke(mmediaplayer,请求,复制);

int result=reply.readInt (;

if(0==result ) {

返回假;

}elseif(1==result ) )。

返回真;

}

}catch(exceptione ) {

e.getCause ().printStackTrace );

} finally {

request.recycle (;

reply.recycle (;

}

}

反射调用步骤:

(1)获取相关类的类class

Class cls=mMediaPlayer.getClass (;

或者用包名获取:

class cls=class.forname (" Android.media.media player " )

)从方法名称中获取方法接口,如果方法具有参数,则必须传递参数的class

方法方法=cls.getdeclaredmethod (“invoke”,Parcel.class,Parcel.class );

)3)用Method的invoke接口实现方法调用时,需要将参数传递给:

method.invoke(mmediaplayer,请求,复制);

2 .出现的问题

用这种方法调用会发现无效,以下error信息:01-0108336031336042.270 w/system.err (1475 ) : Java.lang.reflect.invocationion

01-0108:31336042.270 w/system.err (1475 ) : at Java.lang.reflect.method.invoke native (本机方法) )。

01-0108336031336042.270 w/system.err (1475 ) : at Java.lang.reflect.method.invoke (method.Java 3360511 ) )

这个问题进行了很久,但是反射调用的方法应该没有问题。 错误应该是其他的。 仔细查看log,发现有以下信息。01-0108336031336042.269 e/parcel (3212 ) : readinganullstringnotsupportedherroted

我没有给任何字符串,但是报告这个错误应该是需要进出另一个字符串。

此时,查看MediaPlayer的源代码,可以看到在selectOrDeselectTrack等方法内部也调用的invoke接口: privatevoidselectordeselecttrack (intindid

throws IllegalStateException {

Parcel request=Parcel.obtain (;

Parcel reply=Parcel.obtain (;

try {

request.writeinterfacetoken (I media _ player;

request.write int (选择? INVOKE_ID_SELECT_TRACK

: INVOKE_ID_DESELECT_TRACK;

request.write int (索引;

invoke (请求、复制);

} finally {

request.recycle (;

reply.recycle (;

}

}

这里面添加了我写的invoke界面和: request.writeinterfacetoken (I media _ player )。

IMEDIA_PLAYER的值为: privatefinalstaticstringimedia _ player=' Android.media.I media player ';

我对这个进行了测试之后,还是没有问题,调用成功了。 此代码意味着识别远程服务的名称。 否则,我不知道启动和操作哪个服务。

实际上,媒体播放器有一种获取Parcel对象的方法,但也隐藏了该方法:公共parcel new request

Parcel parcel=Parcel.obtain (;

parcel.writeinterfacetoken (I media _ player;

返回平行;

}

该方法的内部也调用了writeInterfaceToken接口

3 .其他

如果可以看到源代码,则实际上有一个与每个方法的使用源代码相对应的test示例。 例如,现在所说的invoke方法在源代码中有MediaPlayerInvokeTest.java,其中介绍了如何使用invoke接口。 以下是这个班的内容3360//testsfortheinvokemetetava

publicclassmediaplayerinvoketestextends

activityinstrumentationtestcase2{

privatestaticfinalstringtag=' mediaplayerinvoketest ';

私人媒体播放器播放器;

私有随机射频识别;

公共媒体播放器invoketest (

super (com.Android.mediaframeworktest (,MediaFrameworkTest.class ) );

rnd=new random (calendar.getinstance ().getTimeInMillis ) );

}

@Override

protectedvoidsetup { } throws exception

super.setUp (;

mPlayer=new MediaPlayer (;

}

@Override

protectedvoidteardown { } throws exception {

mPlayer.release (;

super.tearDown (;

}

//Generate a random number,sends it to the ping test player。

@Suppress

@ medium测试

公共语音测试坪() throws Exception { ) )。

mplayer.setdata source (test : invoke _ mock _ media _ player.so? url=ping ';

parcel request=mplayer.new request (;

Parcel reply=Parcel.obtain (;

int val=rnd.nextInt (;

request.writeint(val;

mplayer.invoke (请求,复制);

资产质量(val,reply.readInt );

}

}

这次的成果是学会善于看安卓的源代码。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。