AndroidAutoSize icon indicating copy to clipboard operation
AndroidAutoSize copied to clipboard

AutoSize1.2.1版本导致线程调度抛异常Not in applications main thread

Open hjhrq1991 opened this issue 4 years ago • 11 comments

autosize/src/main/java/me/jessyan/autosize/utils/Preconditions.java中checkMainThread方法的调用导致线程异常,使用Thread或rxJava等线程,执行部分操作会触发"Not in applications main thread"异常。

具体表现: 1.Thread中进行下载并更新通知栏下载进度,下载完成后设置通知栏完成状态点击可安装,这时就会抛出IllegalStateException"Not in applications main thread",完成通知消息无法显示并无法弹出系统安装; 2.

private void setQRImage(String qrcodeString, ImageView mQrcodeImage, boolean isCicle) {
    if (TextUtils.isEmpty(qrcodeString)) return;
    Observable.create(new Observable.OnSubscribe<Bitmap>() {
        @Override
        public void call(Subscriber<? super Bitmap> subscriber) {
            Bitmap bitmap;
            try {
                int size = (int) Utils.dpTopx(255f);
                bitmap = QRCodeUtil.creatQrCode(qrcodeString, size, size, BitmapFactory.decodeResource(mQrcodeImage.getContext().getResources(), R.mipmap.app_icon), 0);
                subscriber.onNext(!isCicle ? bitmap : BitmapUitl.drawRoval(BitmapUitl.ALL, bitmap));
            } catch (WriterException e) {
                e.printStackTrace();
                subscriber.onError(e);
            }

            subscriber.onCompleted();
        }
    }).compose(TransformUtils.<Bitmap>defaultSchedulers())
            .subscribe(new Observer<Bitmap>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(Bitmap bitmap) {
                    mQrcodeImage.setImageBitmap(bitmap);
                }
            });
}

以上代码生成二维码,同样抛出IllegalStateException"Not in applications main thread"

3.同上使用RxJava call中使用Glide.get()方法获取Bitmap,调用两次时同样会抛出异常

4.使用友盟分享SDK进行小程序、单图分享功能,当图片为本地图片时无法进行分享,查看友盟SDK相关代码,同样使用了线程获取本地图片,获取时抛异常导致;

解决:

public static void checkMainThread() {
    if (Looper.myLooper() != Looper.getMainLooper()) {
        throw new IllegalStateException("Not in applications main thread");
    }
}

不应该抛异常,调整成返回值供外部调用即可

public static boolean checkMainThread() {
    return Looper.myLooper() == Looper.getMainLooper();
}

hjhrq1991 avatar Jun 10 '21 02:06 hjhrq1991

能把错误信息栈贴出来吗

JessYanCoding avatar Jun 25 '21 03:06 JessYanCoding

我这边报了同样的错误,应该是判断主线程抛出异常导致 java.lang.IllegalStateException: Not in applications main thread at me.jessyan.autosize.utils.Preconditions.checkMainThread(Preconditions.java:113) at me.jessyan.autosize.AutoSizeCompat.autoConvertDensity(AutoSizeCompat.java:139) at me.jessyan.autosize.AutoSizeCompat.autoConvertDensityBaseOnWidth(AutoSizeCompat.java:112) at me.jessyan.autosize.AutoSizeCompat.autoConvertDensityOfGlobal(AutoSizeCompat.java:57) at com.jee.common.base.BaseActivity.getResources(BaseActivity.kt:123) at com.android.internal.policy.DecorContext.getResources(DecorContext.java:90) at android.view.ViewRootImpl.isShouldDelayMsg4SeamlessLauncher(ViewRootImpl.java:8384) at android.view.ViewRootImpl.dispatchResized(ViewRootImpl.java:8374) at android.view.ViewRootImpl.access$5200(ViewRootImpl.java:168) at android.view.ViewRootImpl$W.resized(ViewRootImpl.java:9913) at android.view.IWindow$Stub.onTransact(IWindow.java:358) at android.os.Binder.execTransactInternal(Binder.java:1028) at android.os.Binder.execTransact(Binder.java:1001)

1Ezreal avatar Jun 30 '21 02:06 1Ezreal

我在外面加了主线程判断之后运行正常, override fun getResources(): Resources { if ( Looper.myLooper() == Looper.getMainLooper()) { AutoSizeCompat.autoConvertDensityOfGlobal(super.getResources()) } return super.getResources() }

1Ezreal avatar Jun 30 '21 02:06 1Ezreal

能把错误信息栈贴出来吗

https://github.com/JessYanCoding/AndroidAutoSize/issues/359#issuecomment-871054381

hjhrq1991 avatar Jun 30 '21 02:06 hjhrq1991

@1Ezreal 在调用 autoConvertDensityOfGlobal 的地方切换到主线程再调用 at com.jee.common.base.BaseActivity.getResources(BaseActivity.kt:123)

JessYanCoding avatar Jul 01 '21 02:07 JessYanCoding

设置 Density 和 获取 Density 如果不在同一个线程,有可能会造成 UI 代码获取到的 Density 不是最新设置的 Density,导致程序未能按预期计划去执行而适配异常,如果不抛异常,开发人员会极难发现这个问题,以及捕捉适配异常的原因,所以抛异常是为了让开发人员在开发阶段就能定位这个问题,从而做出相应的处理,如果不抛异常,崩溃虽然不会发生,但是会把一个隐患暴露在你的生产环境

JessYanCoding avatar Jul 01 '21 02:07 JessYanCoding

设置 Density 和 获取 Density 如果不在同一个线程,有可能会造成 UI 代码获取到的 Density 不是最新设置的 Density,导致程序未能按预期计划去执行而适配异常,如果不抛异常,开发人员会极难发现这个问题,以及捕捉适配异常的原因,所以抛异常是为了让开发人员在开发阶段就能定位这个问题,从而做出相应的处理,如果不抛异常,崩溃虽然不会发生,但是会把一个隐患暴露在你的生产环境

嗯,确实如此,我在Activity基类里

@Override
public Resources getResources() {
    AutoSizeCompat.autoConvertDensity(super.getResources(), getSizeInDp(), isBaseOnWidth());
    return super.getResources();
}

中会抛异常,增加线程判断后,则全都正常,同时也可以避免Density不是最新的风险。

@Override
public Resources getResources() {
    if (Looper.myLooper() == Looper.getMainLooper()) {
        AutoSizeCompat.autoConvertDensity(super.getResources(), getSizeInDp(), isBaseOnWidth());
    }
    return super.getResources();
}

虽然得增加一行代码,但1.2.1版本的优化,我是同意的。

hjhrq1991 avatar Jul 01 '21 03:07 hjhrq1991

是转主线程执行好一点还是直接判断会好一点呢

1Ezreal avatar Jul 01 '21 04:07 1Ezreal

我这样子弄好像也没问题 CoroutineScope(Dispatchers.Main).launch { AutoSizeCompat.autoConvertDensityOfGlobal(super.getResources()) }

1Ezreal avatar Jul 01 '21 04:07 1Ezreal

最好还是切主线程调用,保证 Density 随时都能同步更新

JessYanCoding avatar Jul 05 '21 08:07 JessYanCoding

设置 Density 和 获取 Density 如果不在同一个线程,有可能会造成 UI 代码获取到的 Density 不是最新设置的 Density,导致程序未能按预期计划去执行而适配异常,如果不抛异常,开发人员会极难发现这个问题,以及捕捉适配异常的原因,所以抛异常是为了让开发人员在开发阶段就能定位这个问题,从而做出相应的处理,如果不抛异常,崩溃虽然不会发生,但是会把一个隐患暴露在你的生产环境

嗯,确实如此,我在Activity基类里

@Override
public Resources getResources() {
    AutoSizeCompat.autoConvertDensity(super.getResources(), getSizeInDp(), isBaseOnWidth());
    return super.getResources();
}

中会抛异常,增加线程判断后,则全都正常,同时也可以避免Density不是最新的风险。

@Override
public Resources getResources() {
    if (Looper.myLooper() == Looper.getMainLooper()) {
        AutoSizeCompat.autoConvertDensity(super.getResources(), getSizeInDp(), isBaseOnWidth());
    }
    return super.getResources();
}

虽然得增加一行代码,但1.2.1版本的优化,我是同意的。

这个解决了我的问题

Quyunshuo avatar Sep 24 '21 08:09 Quyunshuo