Android HandlerThread Looper可以重复使用吗?

时间:2018-01-08 16:58:43

标签: android android-handler android-jobscheduler

我的Android应用使用JobService来执行我的App Widget Refresh。

今天我收到了一份崩溃报告: -

Fatal Exception: java.lang.OutOfMemoryError: Could not allocate JNI Env
       at java.lang.Thread.nativeCreate(Thread.java)
       at java.lang.Thread.start(Thread.java:731)
       at com.research.app_widget.WidgetUpdateJobService.onStartJob(SourceFile:29)
       at android.app.job.JobService$JobHandler.handleMessage(JobService.java:143)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:154)
       at android.app.ActivityThread.main(ActivityThread.java:6776)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)

从崩溃的堆栈跟踪中,我创建了500多个HandlerThread实例

我的onStartJob方法类似于: -

@Override
public boolean onStartJob(final JobParameters params) {

   mServerHandlerThread = new HandlerThread("ServerApplication");
   mServerHandlerThread.start();

    mServerHandler = new Handler(mServerHandlerThread.getLooper(), new Handler.Callback() {
        @Override
        public boolean handleMessage(final Message msg) {
            final int what = msg.what;

            switch (what) {
                case WHAT_WIDGET_REFRESH:
                    refreshWidget(params);
                    break;
                default:
                    Log.e(TAG, "handleMessage: Unexpected WHAT = " + what);
            }

            return true;
        }
    });

    mServerHandler.sendEmptyMessage(WHAT_WIDGET_REFRESH);

    return true;
}

refreshWidget(params)方法如下: -

private void refreshWidget(final JobParameters params) {
    final PersistableBundle persistableBundle = params.getExtras();
    final int[] appWidgetIds = persistableBundle.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);

    if (appWidgetIds == null) {
        Log.e(TAG, "refreshWidget: appWidgetIds array is null");
    } else {
        for (int appWidgetId : appWidgetIds) {
            new WidgetRemoteViewsHelper().configureViews(this.getApplicationContext(), appWidgetId, isListEmpty(persistableBundle));
        }
    }

    jobFinished(params, false);

}

我不明白的是Android启动了100个scheduledJobs的限制,那么我如何设法启动超过500个HandlerThreads?

我想知道的是,以下是可接受的解决方案吗? 例如重用一个HandlerThread Looper实例?

private final HandlerThread mServerHandlerThread;

{
    mServerHandlerThread = new HandlerThread("ServerApplication");
    mServerHandlerThread.start();

}

@Override
public boolean onStartJob(final JobParameters params) {

    mServerHandler = new Handler(mServerHandlerThread.getLooper(), new Handler.Callback() {
        @Override
        public boolean handleMessage(final Message msg) {
            final int what = msg.what;

            switch (what) {
                case WHAT_WIDGET_REFRESH:
                    refreshWidget(params);
                    break;
                default:
                    Log.e(TAG, "handleMessage: Unexpected WHAT = " + what);
            }

            return true;
        }
    });

    mServerHandler.sendEmptyMessage(WHAT_WIDGET_REFRESH);

    return true;
}

从我的测试到目前为止,这种方法似乎按要求工作。我只是对重复使用一个HandlerThread感到不安。

0 个答案:

没有答案