Thursday 8 November 2012

Can't create handler inside thread that has not called Looper.prepare()


Hello Friend ,

Today, I Stuck with a Weird issue. Calling a thread inside ui thread handler. I am facing
"Can't create handler inside thread that has not called Looper.prepare()" error.

After spending lots of time finally , my problem is fixed. Here is my approach.
     1. Calling the Looper.prepare() just next run
     2. Calling Looper.loop()
     3. Finally you need to destroy or kill your looper using- Looper.getMyLooper().quit().


Here is my Code,

Note: Please declare this variable in your class private volatile Looper mMyLooper;


private Handler handler = new Handler() {
 @Override
 public void handleMessage(Message msg) {

 final SyncRequestManager test = new SyncRequestManager(Test.this);
 try {
            message = message.replaceAll("\n", "");
            progressDialog= ProgressDialog.show(Test.this,
                   "", "Shairing please wait....",true);

        new Thread() {
                  public void run() {
                         try{
                             Looper.prepare();
                             JSONObject jsonObject = test.postOnFacebookWall(mess                      age,byteArray);

                                 JSONObject response = jsonObject.getJSONObject("response");
                                 final String iconUrl = response.getString("icon");
                                 Log.i(" Response" , ""+response);
                                 Log.i(" Icon" , ""+iconUrl);

                                      final FacebookUtil fbUtil = new FacebookUtil(ShareMotekon.this);
       fbUtil.postMessageOnWall(message, iconUrl,byteArray);
       sleep(8000);
      } catch (Exception e) {
          Log.d("Exception", e.getMessage());
      }
           progressDialog.dismiss();                       
           mhandler.sendEmptyMessage(0);
     }
   }.start();
 } catch (Exception e) {
 e.printStackTrace();

   }
  }
};


private Handler mhandler = new Handler() {

  @Override
    public void handleMessage(Message msg) {
   btnNext.setEnabled(true);
   Toast.makeText(ShareMotekon.this,
                       "Message Shared Successfully!", Toast.LENGTH_LONG).show();

    Log.d("INSIDE HANDLER","FB SHARE");

    myLooper = Looper.myLooper();
            Looper.loop();
                         myLooper.quit();  
             }
    };


May , this will help some one.
Enjoy Coding :)

Mukesh Kumar

Hi Guys I am from Delhi working as Web/Mobile Application Developer(Android Developer), also have knowledge of Roboelctric and Mockito ,android test driven development... Blogging has been my passion and I think blogging is one of the powerful medium to share knowledge and ideas....

9 comments:

  1. Nice work. keep it up. working fine for me... :)

    ReplyDelete
  2. I love you man, hhahahua, lost a lot of time on this, thanks!

    ReplyDelete
  3. Thanks mate! This solved my problem with my app running a FFmpeg command from a service:
    https://github.com/dentex/ytdownloader

    I just did:

    class ff implements Runnable {

    private Looper myLooper;

    @Override
    public void run() {

    Looper.prepare();

    // code that needed a separated thread

    myLooper = Looper.myLooper();
    Looper.loop();
    myLooper.quit();
    }
    };

    Thread t = new Thread(new ff());
    t.start();

    ReplyDelete
  4. Thanks a lot!!! I have being stocked more than 1h!

    ReplyDelete
  5. Thanks, works nice, you save my App =)

    ReplyDelete

 

Copyright @ 2013 Android Developers Blog.