Android:New Intent在AsyncTask中导致NullPointerException

时间:2014-05-11 15:16:22

标签: android android-intent android-asynctask

我有一个在后台运行的异步任务,它不断通过网络更新我的本地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。 其余的代码:

        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

1 个答案:

答案 0 :(得分:3)

听起来像是内存泄漏。传递WeakReferencesAsyncTasks或其他此类对象时,始终在Context中使用Activity。尝试这样的事情:

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引用并重新创建Activity对象的Context时,就会发生这种情况,例如当您旋转设备或Activity时已经有一段时间了。

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