0

I created a class which extends Handlerand overrided the handleMessage(Message) method.
Created object in Class that extends HandlerThead
here is the code

public class WorkHandler extends Handler {

private Handler responseHandler;
private DownloadListner downloadListner;

public WorkHandler(Looper looper) {
    super(looper);
}


@Override
public void handleMessage(Message msg) {
    super.handleMessage(msg);
    if (msg.what == 0) {
        @SuppressWarnings("unchecked")
        String url = (String) msg.obj;
        Log.i("tag", "Got a request for url: " + url);
        handleRequest(url);
    }
}

public void setResponseHandler(Handler responseHandler) {
    this.responseHandler = responseHandler;
}


public void setDownloadListner(DownloadListner downloadListner) {
    this.downloadListner = downloadListner;
}  

here handleRequest(url); does the image downloading job.

public class DownloderThread extends HandlerThread {

public static final int MESSAGE_DOWNLOAD = 0;
private Map<String, String> mRequestMap = new HashMap<String, String>();
Handler responseHandler;
WorkHandler workHandler;

public DownloderThread(Handler responseHandler) {
    super("DownloaderThread");
    this.responseHandler = responseHandler;
}

DownloadListner mListener;

public void setListener(DownloadListner listener) {
    mListener = listener;
}

@Override
protected void onLooperPrepared() {

    workHandler = new WorkHandler(getLooper());
    workHandler.setResponseHandler(responseHandler);
    workHandler.setDownloadListner(mListener);

}

public void download(String url) {
    mRequestMap.put("URL", url);
    workHandler.obtainMessage(MESSAGE_DOWNLOAD, url).sendToTarget();
}
}  

here the following line gives NullPointerException. Why?

workHandler.obtainMessage(MESSAGE_DOWNLOAD, url).sendToTarget();  

I am sure that it is not due to Handler.obtainMessage().

Activity contains the following code

public class ImageDownloadActivity extends AppCompatActivity implements DownloadListner {
ImageView imageView;
Button button;
Handler responseHandler;
DownloderThread thread;
String url = "http://developer.android.com/design/media/principles_real_objects.png";

boolean isThreadRunning = false;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_image_download);
    responseHandler = new Handler();
    thread = new DownloderThread(responseHandler);
    thread.setListener(this);
    imageView = (ImageView) findViewById(R.id.imageView);
    button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(isThreadRunning){
                Log.i("tag","Already running");
            }else {
                Log.i("tag", "Background thread started");
                thread.start();
                thread.getLooper();
                thread.download(url);
                isThreadRunning = true;
            }
        }
    });
}


@Override
public void onImageDownloadComplete(Bitmap bitmap) {
    imageView.setImageBitmap(bitmap);

}

@Override
protected void onDestroy() {
    super.onDestroy();
    thread.quit();
    Log.i("tag", "Background thread destroyed");
    }
}  

I also did changes in constructor of WorkHandler class but the result is same.
here is the stack trace:

FATAL EXCEPTION: main
Process: com.sophomoreventure.myapplication9, PID: 12914
  java.lang.NullPointerException
  at com.sophomoreventure.myapplication9.DownloderThread.download(DownloderThread.java:41)
  at com.sophomoreventure.myapplication9.ImageDownloadActivity$1.onClick(ImageDownloadActivity.java:43)
  at android.view.View.performClick(View.java:4463)
  at android.view.View$PerformClick.run(View.java:18770)
  at android.os.Handler.handleCallback(Handler.java:808)
  at android.os.Handler.dispatchMessage(Handler.java:103)
  at android.os.Looper.loop(Looper.java:193)
  at android.app.ActivityThread.main(ActivityThread.java:5292)
  at java.lang.reflect.Method.invokeNative(Native Method)
  at java.lang.reflect.Method.invoke(Method.java:515)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
  at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132)
  at dalvik.system.NativeStart.main(Native Method)
Murli Prajapati
  • 8,833
  • 5
  • 38
  • 55

2 Answers2

0

DownloadListener Initialization? can you check the call is made to setListener() in DownloaderThread class? Due to low reputation, posting it as an answer!

Yogi
  • 1,527
  • 15
  • 21
0

Well, as no auto unboxing is involved (which could throw a NullPointerException), either workHandler or the result of workHandler.obtainMessage(…) is null. As you are sure it's not due to Handler.obtainMessage(…) it has to be because workHandler is null. The workHandler is set in onLooperPrepared(…), so verify and make sure it gets called.

Side note: Never rule out something based on assumptions, always verify by testing and/or debugging. Else you can easily look and search at the wrong location…

siegi
  • 5,646
  • 2
  • 30
  • 42