【问题标题】:Android: New Intent causes NullPointerException in AsyncTaskAndroid:新 Intent 在 AsyncTask 中导致 NullPointerException
【发布时间】:2014-05-11 15:16:21
【问题描述】:

我有一个在后台运行的异步任务,它通过网络不断更新我的本地 sqLite 数据库。一切正常,除了我暂停我的应用程序后的一些随机时间。这是我收到错误的部分代码:

public class AsyncHardwareDBUpdate extends AsyncTask {
ImageCellAdapter mImageCellAdapter;
GridView dynGrid;
Context mContext;
Boolean mFinished = false;

HardwareSyncReceiver myHardwareReceiver;
private Handler handler;
public AsyncHardwareDBUpdate(Context mContext) {
        this.mContext = mContext;
    }

@Override
protected Object doInBackground(Object... params) {
    if (mContext != null){

错误转到以下行:

        Intent intentHardwareSync = new Intent(mContext,SyncHardwareStateService.class);

我无法理解,如果我已经检查了 mContext 是否为 null,那么这里有什么可以为 null 的!= null。 其余代码:

        mContext.startService(intentHardwareSync);
      myHardwareReceiver = new HardwareSyncReceiver();
      //register BroadcastReceiver

      IntentFilter intentHardwareSyncFilter = new IntentFilter(SyncHardwareStateService.ACTION_SyncHardwareStateService);

      intentHardwareSyncFilter.addCategory(Intent.CATEGORY_DEFAULT);

      //Handler for the separate Thread


      HandlerThread handlerThread = new HandlerThread("MyNewThread");
      handlerThread.start();

      Looper looper = handlerThread.getLooper();
      // Create a handler for the service
      handler = new Handler(looper);
      // Register the broadcast receiver to run on the separate Thread
      mContext.registerReceiver (myHardwareReceiver, intentHardwareSyncFilter, null, handler);
    }
      return null;
}


05-11 18:07:37.830: E/AndroidRuntime(15063): FATAL EXCEPTION: AsyncTask #1
05-11 18:07:37.830: E/AndroidRuntime(15063): java.lang.RuntimeException: An error occured while executing doInBackground()
05-11 18:07:37.830: E/AndroidRuntime(15063):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
05-11 18:07:37.830: E/AndroidRuntime(15063):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
05-11 18:07:37.830: E/AndroidRuntime(15063):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
05-11 18:07:37.830: E/AndroidRuntime(15063):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
05-11 18:07:37.830: E/AndroidRuntime(15063):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
05-11 18:07:37.830: E/AndroidRuntime(15063):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
05-11 18:07:37.830: E/AndroidRuntime(15063):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
05-11 18:07:37.830: E/AndroidRuntime(15063):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
05-11 18:07:37.830: E/AndroidRuntime(15063):    at java.lang.Thread.run(Thread.java:856)
05-11 18:07:37.830: E/AndroidRuntime(15063): Caused by: java.lang.NullPointerException
05-11 18:07:37.830: E/AndroidRuntime(15063):    at android.content.ContextWrapper.getPackageName(ContextWrapper.java:127)
05-11 18:07:37.830: E/AndroidRuntime(15063):    at android.content.ComponentName.<init>(ComponentName.java:75)
05-11 18:07:37.830: E/AndroidRuntime(15063):    at android.content.Intent.<init>(Intent.java:3350)
05-11 18:07:37.830: E/AndroidRuntime(15063):    at com.smarthomev5.AsyncUpdateThread.AsyncHardwareDBUpdate.doInBackground(AsyncHardwareDBUpdate.java:38)
05-11 18:07:37.830: E/AndroidRuntime(15063):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
05-11 18:07:37.830: E/AndroidRuntime(15063):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
05-11 18:07:37.830: E/AndroidRuntime(15063):    ... 5 more

【问题讨论】:

  • 在 onPostexecute 中启动意图
  • 这行得通,谢谢 :) 仍然是一种意外错误..

标签: android android-intent android-asynctask


【解决方案1】:

对我来说听起来像是内存泄漏。在将ContextActivity 或其他此类对象传递给它时,始终在AsyncTasks 中使用WeakReferences。试试这样的:

public class ExampleAsyncTask extends AsyncTask<Void, Void, Boolean> {

    private final WeakReference<Context> contextReference;

    public ExampleAsyncTask(Context context) {
        this.contextReference = new WeakReference<Context>(context);
    }

    @Override
    protected Boolean doInBackground(Void... params) {

        Context context = this.contextReference.get();
        if(context != null) {
            // Do your work
        }
        return false;
    }

    @Override
    protected void onPostExecute(Boolean aBoolean) {
        super.onPostExecute(aBoolean);

        Context context = this.contextReference.get();
        if(context != null) {
            // Do your work
        }
    }
}

WeakReference 所做的是允许对其引用的对象进行垃圾回收。如果您直接持有引用,则无法对对象进行垃圾回收,这可能导致ThreadsAsyncTasks 中的内存泄漏。例如,当您直接持有 Context 引用并重新创建 Context 对象所在的 Activity 时,例如当您旋转设备或 Activity 在后台一段时间时,就会发生这种情况。

在上面的示例中,您将Context 对象保存在WeakReference 中,并且每次要使用Context 时,您首先必须从WeakReference 中获取它。从WeakReference 获得它后,您可以简单地检查它是否为空。如果它不为空,那么使用Context 是安全的。如果它为空,则Context 或相应的Activity 已被垃圾回收并且不再可用。

【讨论】:

  • 感谢您的快速回答,但这并没有帮助消除错误。无论如何,为了使我的应用程序更稳定,我仍然使用您的提示 :)
猜你喜欢
  • 2011-07-23
  • 1970-01-01
  • 1970-01-01
  • 2011-07-20
  • 1970-01-01
  • 1970-01-01
  • 2018-05-12
  • 1970-01-01
  • 2011-10-25
相关资源
最近更新 更多