GVKun编程网logo

Android Studio升级到3.0,抛出Aapt2Exception异常(android studio aapt errors)

13

此处将为大家介绍关于AndroidStudio升级到3.0,抛出Aapt2Exception异常的详细内容,并且为您解答有关androidstudioaapterrors的相关问题,此外,我们还将为您

此处将为大家介绍关于Android Studio升级到3.0,抛出Aapt2Exception异常的详细内容,并且为您解答有关android studio aapt errors的相关问题,此外,我们还将为您介绍关于android 7.0 抛出 FileUriExposedException异常、Android BadTokenException异常解决案例详解、Android Studio 2.2.1 Gradle同步NullPointerException、Android Studio 3.0 DexArchiveBuilderException的有用信息。

本文目录一览:

Android Studio升级到3.0,抛出Aapt2Exception异常(android studio aapt errors)

Android Studio升级到3.0,抛出Aapt2Exception异常(android studio aapt errors)

android studiao错误:

Android resource linking failed
Output: D:\_ASWorkSpace\phone_new\app\src\main\res\drawable\mm_title_back_btn.xml:4: error: resource drawable/mm_title_back_focused (aka com.smartdoorbell.activity:drawable/mm_title_back_focused) not found.
D:\_ASWorkSpace\phone_new\app\src\main\res\drawable\mm_title_back_btn.xml:5: error: resource drawable/mm_title_back_pressed (aka com.smartdoorbell.activity:drawable/mm_title_back_pressed) not found.
D:\_ASWorkSpace\phone_new\app\src\main\res\drawable\mm_title_back_btn.xml:6: error: resource drawable/mm_title_back_pressed (aka com.smartdoorbell.activity:drawable/mm_title_back_pressed) not found.
D:\_ASWorkSpace\phone_new\app\src\main\res\drawable\mm_title_back_btn.xml:7: error: resource drawable/mm_title_back_normal (aka com.smartdoorbell.activity:drawable/mm_title_back_normal) not found.
error: failed linking file resources.

Command: C:\Users\elaine\.gradle\caches\transforms-1\files-1.1\aapt2-3.2.0-4818971-windows.jar\01420f994b14e5123620886adc2b29c9\aapt2-3.2.0-4818971-windows\aapt2.exe link -I\
D:\adt-bundle-windows-x86_64_with_Android_5.0\sdk\platforms\android-26\android.jar\
--manifest\
D:\_ASWorkSpace\phone_new\app\build\intermediates\merged_manifests\phoneRollupRelease\processPhoneRollupReleaseManifest\merged\AndroidManifest.xml\
-o\
D:\_ASWorkSpace\phone_new\app\build\intermediates\processed_res\phoneRollupRelease\processPhoneRollupReleaseResources\out\resources-phoneRollupRelease.ap_\
-R\
@D:\_ASWorkSpace\phone_new\app\build\intermediates\incremental\processPhoneRollupReleaseResources\resources-list-for-resources-phoneRollupRelease.ap_.txt\
--auto-add-overlay\
--java\
D:\_ASWorkSpace\phone_new\app\build\generated\not_namespaced_r_class_sources\phoneRollupRelease\processPhoneRollupReleaseResources\r\
--proguard-main-dex\
D:\_ASWorkSpace\phone_new\app\build\intermediates\legacy_multidex_aapt_derived_proguard_rules\phoneRollupRelease\processPhoneRollupReleaseResources\manifest_keep.txt\
--custom-package\
com.smartdoorbell.activity\
-0\
apk\
--output-text-symbols\
D:\_ASWorkSpace\phone_new\app\build\intermediates\symbols\phoneRollup\release\R.txt\
--no-version-vectors
Daemon: AAPT2 aapt2-3.2.0-4818971-windows Daemon #0

 

gradle.properties 中添加下面内容

#Tue Oct 17 10:08:09 CST 2017
android.enableAapt2=false

android 7.0 抛出 FileUriExposedException异常

android 7.0 抛出 FileUriExposedException异常

官方解释

参考官方解释 https://developer.android.com/reference/android/os/FileUriExposedException.html

解决办法 https://developer.android.com/reference/android/support/v4/content/FileProvider.html

大致处理步骤:

1. 在mainfest中加入FileProvider注册

<manifest>
    ...
    <application>
        ...
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="App包名.fileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
             <meta-data
                   android:name="android.support.FILE_PROVIDER_PATHS"
                   android:resource="@xml/file_paths" />
        </provider>
        ...
    </application>
</manifest>

2. 新建res/xml/file_paths.xml文件

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="my_images" path="images/"/>
    <files-path name="my_docs" path="docs/"/>
</paths>
<paths> 中可以定义以下子节点
子节点 对应路径 示例
files-path Context.getFilesDir() <files-path name="name" path="path" />
cache-path Context.getCacheDir() <cache-path name="name" path="path" />
external-path Environment.getExternalStorageDirectory() <external-path name="name" path="path" />
external-files-path Context#getExternalFilesDir(String) Context.getExternalFilesDir(null) <external-files-path name="name" path="path" />
external-cache-path Context.getExternalCacheDir() <external-cache-path name="name" path="path" />

3. 使用示例

File imagePath = new File(Context.getFilesDir(), "images");
File newFile = new File(imagePath, "default_image.jpg");
Uri contentUri = FileProvider.getUriForFile(getContext(), "App包名.fileprovider", newFile);

4. 遇到的问题

Attempt to invoke virtual method ''android.content.res.XmlResourceParser android.content.pm.PackageItemInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)'' on a null object reference

原因:mainfest中 android:authorities 与 代码 FileProvider.getUriForFile(getContext(), "App包名.fileprovider", newFile);App包名.fileprovider不一致

Android BadTokenException异常解决案例详解

Android BadTokenException异常解决案例详解

image.png

线上出现了如上的 crash,第一解决反应是在 show dialog 之前做个 isFinish 和 isDestroyed 判断,当我翻开代码正要解决时,我惊了,原来已经做过了如上的判断检测,示例伪代码如下:

public void showDialog(Activity activity){
    new OkHttp().call(new Callback(){
        void onSucess(Response resp){
            if(activity!=null && !activity.isFinishing() && !activity.isDestroed()){
               new Dialog().show()   
            }
        }
    })
}

这该如何是好,正常的判断解决不了 badToken 问题,在焦灼之际重新回顾一下 framework 的源码,AMS 分发 onDestroy 生命周期在 ActivityRecord 类(基于 Android 10 源码):

image.png

1、第一个红框调用 ApplicationThread binder 代理的 scheduleTransaction 方法,回执的生命周期为 DestroyActivityItem,scheduleTransaction 方法将包裹着 DestroyActivityItem 的 ClientTransaction 分发给 ActivityThread , ActivityThread 的父类会处理 scheduleTransaction ,并将 ClientTransaction 切换到主线程进行进行 Activity 的生命周期调度。为什么要把这个过程理清,后面解决部分会 hook 该过程

2、第二个红框是 Destroy 生命周期超时处理,超时时间为 10s,如果分发给应用进程的 onDestroy 10s 内处理未结束,AMS 也会在超时的时候,将该 Activity 标记为已销毁,并通知 WMS 删除该 Activity 的 token。

通过这两点,我们可以推理出我们应用当时处于什么环境:

AMS 已经将销毁的指令告诉应用进程了,但应用进程一直在处理自己的事情,未处理 Destroy 生命周期(从业务代码 > isDestroyed> = false 可知),然后 AMS 的 10s 超时机制到了,并通知 WMS 移除 token,然后我们的业务代码异步请求网络完成,判断 isFinish 和 isDestroyed 都是有效的,然后就顺理成章的执行了 show dialog 操作,发生了该异常。

我们可以画个简单的图:

image.png

解决办法1

既然是 AMS 发的 destroy 消息被主线程的其他任务阻塞导致一直没执行,那么,我们可以在 show dialog 的时候去检查一下主线程的 MessageQueue,遍历一下所有的 Message,看看里面有没有 Destroy Message,如果有的话,说明当前会发生 badToken 异常。

查看了下 MessageQueue 的 mMessages 字段,发现该字段被标注为 UnsupportedAppUsage 注解,看起来不支持给 app 调用,先不管,我们先 hook 一番,代码就不贴了,后面给出示例代码,一顿操作猛如虎,发现是可以通过反射拿到 Message 的,然后接下来就可以通过递归遍历 Message next,取出所有的 Message。

在拿到 Message 的同时,我们要怎么识别出这是个 Destroy Message 呢?

这要看不同的系统版本:

  • Android P 之前(不包括 P),destroy message 是通过给 Message.what = DESTROY_ACTIVITY 来进行分发的,DESTROY_ACTIVITY = 109,那么我们就可以判断,只要 Message 中的 what 为 109 即可判断当前是 Destroy Message。
  • Android P 之后(包括 P),AMS 的生命周期分发改了,不再是通过调用 ApplicationThread 的某个方法,然后根据 DESTROY_ACTIVITY 这种数值型来分发,而是全部统一走 ApplicationThread 的 scheduleTransaction 方法,生命周期标识是存放在参数 ClientTransaction 中,在切换到主线程时,会执行 ClientTransaction 的 getLifecycleStateRequest 方法,拿到 ActivityLifecycleItem,ActivityLifecycleItem 的子类很多,其中就有 DestroyActivityItem ,我们只需要判断 Message 中是否有 DestroyActivityItem 即可

部分示例代码如下:

fun isOnDestroyMsgExit(): Boolean {
  val msg = hookMessage()
  return nextMessage(::isOnDestroyMsgExit, msg)
}
​
private fun isOnDestroyMsgExit(msg: Message): Boolean {
  if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
    if (msg.what == EXECUTE_TRANSACTION && msg.obj != null) {
        val clazz = msg.obj::class.java
        if (TextUtils.equals(clazz.name, "android.app.servertransaction.ClientTransaction")) {
           val method = clazz.getDeclaredMethod("getLifecycleStateRequest")
           method.isAccessible = true
           val obj =  method.invoke(msg.obj)
           if (obj!=null){
              val clazzName = obj::class.java.name
              if (TextUtils.equals(clazzName,"android.app.servertransaction.DestroyActivityItem") ){
                  return true
              }
           }
        }
     }
  } else {
    return msg.what == DESTROY_ACTIVITY
  }
  return false
}

demo 验证如下,destroy message 被成功拿到:

image.png

那么我们的业务代码的判断就可以改造成:

public void showDialog(Activity activity){
    new OkHttp().call(new Callback(){
        void onSucess(Response resp){
            if(activity!=null 
               && !activity.isFinishing() 
               && !activity.isDestroed()
                // 多加一条判断,判断当前消息队列中没有 destroy message
               && !BadTokenUtils.isOnDestroyMsgExit()
              ){
               new Dialog().show()   
            }
        }
    })
}

这种方式有个缺点,大量的 hook message 会造成应用的不稳定性。

解决方法2

业务代码是在请求网络成功的时候进行的 dialog 展示,这时候又有人问了,这是在子线程,怎么能 show dialog 呢?其实不然,ViewRoomImpl 检验线程,是判断创建 ViewRootImpl 时的线程与 requestLayout 的线程一致,是一样的话,即可直接操作。

但这一点提醒到了我,我们能否将 show dialog 的逻辑放到主线程来做,MessageQueue 已经有了 destroy 消息,如果我们再发一个 show dialog message 的话,那肯定是排在 destroy message 后面的(Message 会根据 when 来整理链表),那么,先处理的 destroy message 会使 isDestroyed 为 true,这样,我们的判断就生效了,示例图如下:

image.png

代码则变为:

public void showDialog(Activity activity){
   new OkHttp().call(new Callback(){
       void onSucess(Response resp){
          // 先判断一次
          if(activity!=null  && !activity.isFinishing() && !activity.isDestroed() ){ 
              // 切到主线程,post 一个 message 给 MQ
              activity.runOnUiThread(new Runnable() {
                @Override
                 public void run() {
                   // 再判断一次
            if(activity!=null  && !activity.isFinishing() && !activity.isDestroed() ){
                       new Dialog().show()   
                    }
                 }
              });
           }
    });
}

缺点:runOnUiThread 只对异步线程有效,因为在主线程会被直接执行,并不会插入一条 message,解决办法也有,如果当前是在主线程的话,可以通过 handler 的方式发送一条 message,如 Handler(Looper.getMainLooper()).post()

总结

大部分场景都能通过 isFinish 和 isDestroyed 判断来解决,但对于主线程做耗时任务导致 destroy message 没有被正确处理情况,还是得回归到应用稳定性治理层面,虽然能解决 badToken 问题,但本质上应用卡顿问题依然存在.

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注的更多内容!

您可能感兴趣的文章:
  • Android audio音频流数据异常问题解决分析
  • Android Studio 4.0新特性及升级异常问题的解决方案
  • 解决android viewmodel 数据刷新异常的问题
  • loadavg数据异常引发问题起源分析

Android Studio 2.2.1 Gradle同步NullPointerException

Android Studio 2.2.1 Gradle同步NullPointerException

我已经安装了android studio 2.2并创建了新项目,但是gradle同步每次都失败,并且出现以下异常.

Error:Cause: java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at java.util.Arrays$ArrayList.<init>(Arrays.java:3813)
at java.util.Arrays.asList(Arrays.java:3800)
at com.intellij.openapi.util.io.FileUtilRt.doCreateTempFile(FileUtilRt.java:399)
at com.intellij.openapi.util.io.FileUtilRt.createTempFile(FileUtilRt.java:361)
at com.intellij.openapi.util.io.FileUtilRt.createTempFile(FileUtilRt.java:341)
at com.intellij.openapi.util.io.FileUtilRt.createTempFile(FileUtilRt.java:334)
at com.intellij.openapi.util.io.FileUtil.createTempFile(FileUtil.java:1479)
at com.android.tools.idea.gradle.util.GradleUtil.addInitScriptCommandLineOption(GradleUtil.java:1064)
at com.android.tools.idea.gradle.util.GradleUtil.addLocalMavenRepoInitScriptCommandLineOption(GradleUtil.java:1057)
at com.android.tools.idea.gradle.util.GradleUtil.addLocalMavenRepoInitScriptCommandLineOption(GradleUtil.java:1023)
at com.android.tools.idea.gradle.project.AndroidGradleProjectResolver.getExtraCommandLineArgs(AndroidGradleProjectResolver.java:345)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver.doResolveProjectInfo(GradleProjectResolver.java:175)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver.access$300(GradleProjectResolver.java:73)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver$ProjectConnectionDatanodefunction.fun(GradleProjectResolver.java:768)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver$ProjectConnectionDatanodefunction.fun(GradleProjectResolver.java:752)
at org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper.execute(GradleExecutionHelper.java:238)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver.resolveProjectInfo(GradleProjectResolver.java:112)
at org.jetbrains.plugins.gradle.service.project.GradleProjectResolver.resolveProjectInfo(GradleProjectResolver.java:73)
at com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolverImpl$1.produce(RemoteExternalSystemProjectResolverImpl.java:41)
at com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolverImpl$1.produce(RemoteExternalSystemProjectResolverImpl.java:37)
at com.intellij.openapi.externalSystem.service.remote.AbstractRemoteExternalSystemService.execute(AbstractRemoteExternalSystemService.java:59)
at com.intellij.openapi.externalSystem.service.remote.RemoteExternalSystemProjectResolverImpl.resolveProjectInfo(RemoteExternalSystemProjectResolverImpl.java:37)
at com.intellij.openapi.externalSystem.service.remote.wrapper.ExternalSystemProjectResolverWrapper.resolveProjectInfo(ExternalSystemProjectResolverWrapper.java:49)
at com.intellij.openapi.externalSystem.service.internal.ExternalSystemResolveProjectTask.doExecute(ExternalSystemResolveProjectTask.java:51)
at com.intellij.openapi.externalSystem.service.internal.AbstractExternalSystemTask.execute(AbstractExternalSystemTask.java:138)
at com.intellij.openapi.externalSystem.service.internal.AbstractExternalSystemTask.execute(AbstractExternalSystemTask.java:124)
at com.intellij.openapi.externalSystem.util.ExternalSystemUtil$3.execute(ExternalSystemUtil.java:419)
at com.intellij.openapi.externalSystem.util.ExternalSystemUtil$4$2.run(ExternalSystemUtil.java:500)
at com.intellij.openapi.progress.impl.CoreProgressManager$TaskRunnable.run(CoreProgressManager.java:563)
at com.intellij.openapi.progress.impl.CoreProgressManager$2.run(CoreProgressManager.java:142)
at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:446)
at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:392)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:54)
at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:127)
at com.intellij.openapi.progress.impl.ProgressManagerImpl$1.run(ProgressManagerImpl.java:126)
at com.intellij.openapi.application.impl.ApplicationImpl$8.run(ApplicationImpl.java:369)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

是否有人遇到相同问题或找到任何解决方案?

解决方法:

感谢@keddy 1201他的评论挽救了我的性命.我尝试卸载studio和java sdk,然后用以前的版本和新版本重新安装了几次.

尝试以管理员身份运行Studio以解决问题

Android Studio 3.0 DexArchiveBuilderException

Android Studio 3.0 DexArchiveBuilderException

编译仪器测试时出现此错误。

错误:com.android.builder.dexing.DexArchiveBuilderException:无法处理/Users/rafaelruizmunoz/SourceTree/Weather/app/build/intermediates/transforms/desugar/androidTest/debug/1.jar

错误:com.android.builder.dexing.DexArchiveBuilderException:分解org / assertj /
core / api / LongPredicateAssert.class时出错

错误:com.android.dx.cf.code.SimException:默认或静态接口方法不带–min-sdk-version> = 24

我尝试启用/禁用multiDexEnabled自己的功能,build.gradle但无济于事。

androidbuild.gradle

android {    compileSdkVersion 27    defaultConfig {        applicationId "com.**.weather"        minSdkVersion 16        targetSdkVersion 27        versionCode 1        versionName "1.0"        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"        multiDexEnabled = true    }    buildTypes {        release {            minifyEnabled false            proguardFiles getDefaultProguardFile(''proguard-android.txt''), ''proguard-rules.pro''        }    }    compileOptions {        targetCompatibility 1.8        sourceCompatibility 1.8    }}

答案1

小编典典

gradle.properties添加android.enableD8=true这应该工作。

请注意,导出并上传apk以启用d8播放商店时,存在一个已知的错误。从Play商店下载该应用后,该应用将无法在某些设备上运行。

https://issuetracker.google.com/issues/64740479

关于Android Studio升级到3.0,抛出Aapt2Exception异常android studio aapt errors的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于android 7.0 抛出 FileUriExposedException异常、Android BadTokenException异常解决案例详解、Android Studio 2.2.1 Gradle同步NullPointerException、Android Studio 3.0 DexArchiveBuilderException等相关内容,可以在本站寻找。

本文标签: