Search code examples
androidandroid-serviceprogressdialogandroid-looper

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


In my app I have a sercice class that it has this method to show progress dialog when do something :

private void openprogresdialog() {

new AsyncTask<Integer, Integer, Boolean>()
{
    ProgressDialog progressDialog;

    @Override
    protected void onPreExecute()
    {
        progressDialog = ProgressDialog.show(thisActivity, "Dialog","Loading...");
    }

    @Override
    protected Boolean doInBackground(Integer... params)
    {
        if (params == null)
        {
            return false;
        }
        try
        {
            Thread.sleep(params[0]);
        }
        catch (Exception e)
        {
            Log.e("tag", e.getMessage());
            return false;
        }

        return true;
    }

    @Override
    protected void onPostExecute(Boolean result)
    {
        progressDialog.dismiss();
        AlertDialog.Builder b = new AlertDialog.Builder(thisActivity);
        b.setTitle(android.R.string.dialog_alert_title);
        if (result)
        {
            b.setMessage("Download succeeded");
        }
        else
        {
            b.setMessage("Download failed");
        }
        b.setPositiveButton(getString(android.R.string.ok),
                new DialogInterface.OnClickListener()
                {

                    @Override
                    public void onClick(DialogInterface dlg, int arg1)
                    {
                        dlg.dismiss();
                    }
                });
        b.create().show();
    }
}.execute(2000);

new Thread()
{
    @Override
    public void run()
    {

        DialogInterface progressDialog = null;
        progressDialog.dismiss();
    }
}.start();
}

I want that while app do it's work progress dialog will show but when i run app i get this error :

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

How can i fix it?

EDIT :

public class MyService extends Service {
    private static final String TAG = "MyService";
    Thread readthread;
    final MyService thisActivity = this;
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        final ParentActivityData data = intent.getParcelableExtra("DATA");

        readthread = new Thread(new Runnable() {
            public void run() {
                // SOME CODE TO EXECUTE //
                }
                openprogresdialog();
            }
        });

        readthread.start();

        Log.d(TAG, "onCreate");

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onCreate() {
    }

    @Override
    public void onDestroy() {

    }
}

Solution

  • You have

    readthread = new Thread(new Runnable() {
                public void run() {
    

    In the thread's run method you ahve

    openprogresdialog();
    

    In openprogresdialog you have a Asynctask and a thread.

    Asynctask must be loaded on the ui thread. Check the topic Threading Rules in the link below.

    http://developer.android.com/reference/android/os/AsyncTask.html

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

    You cannot update ui in a background thread. Ui should be updated on the ui thread. Your Asynctask looks fine but must be loaded on the ui thread.

    Also remove the below which is useless. Will also give NullPointerException since progressDialog is not initialized and you call dismiss before initialization

    new Thread()
    {
        @Override
        public void run()
        {
    
            DialogInterface progressDialog = null;
            progressDialog.dismiss(); // even if initialized cannot update ui in a thread
        }
    }.start();