首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android模拟器中替换系统应用的方法

Android模拟器中替换系统应用的方法

作者头像
drunkdream
发布2018-07-06 18:09:19
1.5K0
发布2018-07-06 18:09:19
举报
文章被收录于专栏:醉梦轩醉梦轩

Android模拟器6.0版本进入系统时,桌面应用com.android.launcher3会发生随机Crash。

W/System.err( 1611): java.lang.IllegalArgumentException: Wrong state class, expecting View State but received class android.appwidget.AppWidgetHostView$ParcelableSparseArray instead. This usually happens when two views of different type have the same id in the same hierarchy. This view’s id is id/0x3. Make sure other views do not use the same id. W/System.err( 1611): at android.view.View.onRestoreInstanceState(View.java:13772) W/System.err( 1611): at android.widget.TextView.onRestoreInstanceState(TextView.java:3784) W/System.err( 1611): at android.view.View.dispatchRestoreInstanceState(View.java:13748) W/System.err( 1611): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2894) W/System.err( 1611): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2894) W/System.err( 1611): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2894) W/System.err( 1611): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2894) W/System.err( 1611): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2894) W/System.err( 1611): at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2894) W/System.err( 1611): at android.view.View.restoreHierarchyState(View.java:13726) W/System.err( 1611): at com.android.internal.policy.impl.PhoneWindow.restoreHierarchyState(PhoneWindow.java:2009) W/System.err( 1611): at android.app.Activity.onRestoreInstanceState(Activity.java:1074) W/System.err( 1611): at com.android.launcher3.Launcher.onRestoreInstanceState(Launcher.java:2013)

网上找到如下解决方法:

packages/apps/Launcher3/src/com/android/launcher3/Launcher.java:

public void onRestoreInstanceState(Bundle state) {
    // Wrap the code block will throw runtinme exception in try / catch block
    // ----------------------------------------------------------------------
    //super.onRestoreInstanceState(state);
    //for (int page: mSynchronouslyBoundPages) {
    //    mWorkspace.restoreInstanceStateForChild(page);
    //}

    try {
        super.onRestoreInstanceState(state);
        for (int page: mSynchronouslyBoundPages) {
            mWorkspace.restoreInstanceStateForChild(page);
        }
    } catch (Exception e) {
        Log.e(TAG, "Exception in onRestoreInstanceState():");
        e.printStackTrace();
    }
}

编译后替换掉镜像中的文件:

/system/priv-app/Launcher3/Launcher3.apk /system/priv-app/Launcher3/oat/x86/Launcher3.odex

重启后报了另外一个错误:

java.lang.RuntimeException: Unable to get provider com.android.launcher3.LauncherProvider: java.lang.ClassNotFoundException: Didn’t find class “com.android.launcher3.LauncherProvider” on path: DexPathList[[zip file “/system/priv-app/Launcher3/Launcher3.apk”],nativeLibraryDirectories=[/system/priv-app/Launcher3/lib/x86, /vendor/lib, /system/lib]] at android.app.ActivityThread.installProvider(ActivityThread.java:5156) at android.app.ActivityThread.installContentProviders(ActivityThread.java:4748) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4688) at android.app.ActivityThread.-wrap1(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1405) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) Caused by: java.lang.ClassNotFoundException: Didn’t find class “com.android.launcher3.LauncherProvider” on path: DexPathList[[zip file “/system/priv-app/Launcher3/Launcher3.apk”],nativeLibraryDirectories=[/system/priv-app/Launcher3/lib/x86, /vendor/lib, /system/lib]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) at java.lang.ClassLoader.loadClass(ClassLoader.java:511) at java.lang.ClassLoader.loadClass(ClassLoader.java:469) at android.app.ActivityThread.installProvider(ActivityThread.java:5141) … 10 more Suppressed: java.io.IOException: No original dex files found for dex location /system/priv-app/Launcher3/Launcher3.apk at dalvik.system.DexFile.openDexFileNative(Native Method) at dalvik.system.DexFile.openDexFile(DexFile.java:295) at dalvik.system.DexFile.(DexFile.java:80) at dalvik.system.DexFile.(DexFile.java:59) at dalvik.system.DexPathList.loadDexFile(DexPathList.java:279) at dalvik.system.DexPathList.makePathElements(DexPathList.java:248) at dalvik.system.DexPathList.(DexPathList.java:120) at dalvik.system.BaseDexClassLoader.(BaseDexClassLoader.java:48) at dalvik.system.PathClassLoader.(PathClassLoader.java:65) at android.app.ApplicationLoaders.getClassLoader(ApplicationLoaders.java:58) at android.app.LoadedApk.getClassLoader(LoadedApk.java:376) at android.app.LoadedApk.makeApplication(LoadedApk.java:568) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4680) … 8 more

猜测是因为编译时用的art库版本与模拟器中不一致,导致生成的oat文件不匹配。解决方法是把dex文件拷贝到模拟器里,然后使用dex2oat编译下。

编译出来的dex文件(Launcher3.apk中不包含dex文件)路径是:

out/target/common/obj/APPS/Launcher3_intermediates/classes.dex

使用如下命令可以在/data/local/tmp目录下生成Launcher3.odex文件,/data/local/tmp/Launcher3.dex是要输入的dex文件路径。

5.0中执行的命令

> dex2oat --runtime-arg -Xms64m --runtime-arg -Xmx512m --dex-file=/data/local/tmp/Launcher3.dex --dex-location=/system/priv-app/Launcher3/Launcher3.apk --oat-file=/data/local/tmp/Launcher3.odex --android-root=/system --instruction-set=x86 --instruction-set-features=default --include-patch-information --runtime-arg -Xnorelocate --no-include-debug-symbols

6.0中执行的命令

> dex2oat --runtime-arg -Xms64m --runtime-arg -Xmx512m --dex-file=/data/local/tmp/Launcher3.dex --dex-location=/system/priv-app/Launcher3/Launcher3.apk --oat-file=/data/local/tmp/Launcher3.odex --android-root=/system --instruction-set=x86 --instruction-set-variant=x86 --instruction-set-features=default --include-patch-information --runtime-arg -Xnorelocate --no-generate-debug-info --abort-on-hard-verifier-error

另外一种解决方法是: 修改

build/target/board/generic_x86/BoardConfig.mk

文件,注释掉:

WITH_DEXPREOPT ?= true

这样,编译后的apk中就会包含dex文件,在模拟器第一次开机时会自动进行dexopt操作。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档