当试图注册embedded式apk广播接收器时获取“java.lang.reflect.InvocationTargetException”

我的应用程序有一个embedded的APK,我需要从我的主要APK在内部APK注册一个BroadcastReceiver

内部APK不安装在系统上; 我必须dynamic加载它。 所以,我正在使用reflection来调用内部APK中的一个方法,它有注册BroadcastReceiver代码。 内部APK的这个接收器应该调用相关的广播。

在尝试注册BroadcastReceiver出现错误。 BroadcastReceiver甚至有可能以这种方式注册,并且function齐全? 例外和代码如下

错误相关日志:

 08-24 08:31:26.915: D/MainApp(1957): invoke method 08-24 08:31:26.955: D/InnerApp(1957): Register receiver 08-24 08:31:26.955: W/System.err(1957): java.lang.reflect.InvocationTargetException 08-24 08:31:26.965: W/System.err(1957): at java.lang.reflect.Method.invokeNative(Native Method) 08-24 08:31:26.965: W/System.err(1957): at java.lang.reflect.Method.invoke(Method.java:515) 08-24 08:31:26.965: W/System.err(1957): at com.example.ea_mainapp.MainApp.invokeService(MainApp.java:105) 08-24 08:31:26.965: W/System.err(1957): at com.example.ea_mainapp.MainApp.onCreate(MainApp.java:40) 08-24 08:31:26.965: W/System.err(1957): at android.app.Activity.performCreate(Activity.java:5231) 08-24 08:31:26.975: W/System.err(1957): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087) 08-24 08:31:26.975: W/System.err(1957): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159) 08-24 08:31:26.975: W/System.err(1957): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245) 08-24 08:31:26.975: W/System.err(1957): at android.app.ActivityThread.access$800(ActivityThread.java:135) 08-24 08:31:26.975: W/System.err(1957): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 08-24 08:31:26.975: W/System.err(1957): at android.os.Handler.dispatchMessage(Handler.java:102) 08-24 08:31:26.975: W/System.err(1957): at android.os.Looper.loop(Looper.java:136) 08-24 08:31:26.975: W/System.err(1957): at android.app.ActivityThread.main(ActivityThread.java:5017) 08-24 08:31:26.975: W/System.err(1957): at java.lang.reflect.Method.invokeNative(Native Method) 08-24 08:31:26.975: W/System.err(1957): at java.lang.reflect.Method.invoke(Method.java:515) 08-24 08:31:26.975: W/System.err(1957): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 08-24 08:31:26.975: W/System.err(1957): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 08-24 08:31:26.975: W/System.err(1957): at dalvik.system.NativeStart.main(Native Method) 08-24 08:31:26.985: W/System.err(1957): Caused by: java.lang.NullPointerException 08-24 08:31:26.985: W/System.err(1957): at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:467) 08-24 08:31:26.985: W/System.err(1957): at com.example.ea_innerapp.InnerApp.register(InnerApp.java:50) 08-24 08:31:26.985: W/System.err(1957): ... 18 more` 

主应用程序的相关代码:

 // invoke method Log.d(TAG,"invoke method"); final String apkFile =TARGET_BASE_PATH+"EA_innerApp.apk"; String className = "com.example.ea_innerapp.InnerApp"; String methodToInvoke = "register"; final File optimizedDexOutputPath = getDir("outdex", 0); DexClassLoader dLoader = new DexClassLoader(apkFile,optimizedDexOutputPath.getAbsolutePath(), null,ClassLoader.getSystemClassLoader().getParent()); try { Class<?> loadedClass = dLoader.loadClass(className); Object obj = (Object)loadedClass.newInstance(); @SuppressWarnings("rawtypes") Class noparams[] = {}; Method m = loadedClass.getMethod(methodToInvoke, noparams); Object oNoparams[] = {}; m.invoke(obj, oNoparams); } catch (ClassNotFoundException e) {.... } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } 

被调用方法的代码“com.example.ea_innerapp.InnerApp.register”:

 Log.d(TAG, "Register receiver"); IntentFilter filter=new IntentFilter(); filter.addAction("com.example.ea_mainapp.i"); registerReceiver(obj_InnerReceiver,filter); 

Solutions Collecting From Web of "当试图注册embedded式apk广播接收器时获取“java.lang.reflect.InvocationTargetException”"

我已经解决了这个问题。

问题的确定:

staketrace例外的主要部分是

 08-24 08:31:26.985: W/System.err(1957): Caused by: java.lang.NullPointerException 08-24 08:31:26.985: W/System.err(1957): at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:467) 08-24 08:31:26.985: W/System.err(1957): at com.example.ea_innerapp.InnerApp.register(InnerApp.java:50) 

我查看了“android.content.ContextWrapper.registerReceive”的代码来find主要原因。 下面给出了ContextWrapper类的相关代码

 464 @Override 465 public Intent registerReceiver( 466 BroadcastReceiver receiver, IntentFilter filter) { 467 return mBase.registerReceiver(receiver, filter); 468 } 

参考: http : //grepcode.com/file/repo1.maven.org/maven2/org.robolectric/android-all/4.4_r1-robolectric-1/android/content/ContextWrapper.java#ContextWrapper.0mBase

错误是在第467行,这是"return mBase.registerReceiver(receiver, filter);" 。 在这里, mBase是类“android.content.Context”的对象。 在“com.example.ea_innerapp.InnerApp ”类中,Context的值为null ,因为它是embedded式apk的类。 这就是我得到例外的原因。

解:

我需要提供一个上下文值。 所以,我把主apk的Context作为parameter passing给“com.example.ea_innerapp.InnerApp.register”

“com.example.ea_innerapp.InnerApp.register”正在调用“ android.content.ContextWrapper.registerReceive” ,它没有接收Context作为参数。 所以,我直接调用“android.content.Context.registerReceiver” ,使用主apk提供的上下文 。 修改“com.example.ea_innerapp.InnerApp.register”

 public void register(Context param_ctx){ ...... param_ctx.registerReceiver(obj_InnerReceiver,filter); } 

请注意,您必须保存param_ctx的值,并在注册接收者的同时使用它,否则会出错。 要取消注册接收器,你会打电话

 ctx.unregisterReceiver(obj_InnerReceiver); // ctx is the value that was passed to "com.example.ea_innerapp.InnerApp.register"