Search code examples
androidandroid-asynctaskandroid-dialogandroid-progressbarandroid-runonuithread

Android ProgressDialog not working together with AsyncTask


I'm trying to run a function on another thread. Unfortunately it just keeps on going without dismissing. The Try catch works if i don't have it within the run function. I Thought it could be the AsyncTask that i have inside the function.

i also catch this error

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

Here is my code

    btnSubmit.setOnClickListener(new View.OnClickListener() {
    InputStream is = null;

    @Override
    public void onClick(View v) {


        pDialog = ProgressDialog.show(AvvikelseActivity.this, "Registrerar", "Vänta");

        //Start the function here


        //start a new thread to process job
        new Thread(new Runnable() {
            @Override
            public void run() {
                //heavy job here
                //send message to main thread
                try {

                    Bitmap immage = null;
                    //preapare the image
                    immage = BitmapFactory.decodeFile(imgurl);
                    final int maxSize = 960;
                    int outWidth;
                    int outHeight;
                    int inWidth = immage.getWidth();
                    int inHeight = immage.getHeight();
                    if (inWidth > inHeight) {
                        outWidth = maxSize;
                        outHeight = (inHeight * maxSize) / inWidth;
                    } else {
                        outHeight = maxSize;
                        outWidth = (inWidth * maxSize) / inHeight;
                    }
                    Bitmap resizedBitmap = Bitmap.createScaledBitmap(immage, outWidth, outHeight, false);


                    //initiate string imagedata, which will be the string for the actual image
                    String imagedata = null;
                    //encode the image
                    imagedata = encodeTobase64(immage);

                    //Setting nameValuePairs
                    final List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);

                    //adding the string variables
                    nameValuePairs.add(new BasicNameValuePair("reporter", reporter));
                    nameValuePairs.add(new BasicNameValuePair("department", department));
                    nameValuePairs.add(new BasicNameValuePair("errortype", errortype));
                    nameValuePairs.add(new BasicNameValuePair("title", title));
                    nameValuePairs.add(new BasicNameValuePair("description", description));
                    nameValuePairs.add(new BasicNameValuePair("percaution", percaution));
                    nameValuePairs.add(new BasicNameValuePair("imgurl", imgurl));
                    nameValuePairs.add(new BasicNameValuePair("dataset", dataset));
                    nameValuePairs.add(new BasicNameValuePair("image", imagedata));
                    nameValuePairs.add(new BasicNameValuePair("phoneid", android_id));
                    nameValuePairs.add(new BasicNameValuePair("typ", TAG_TYP));

                    //Task to upload the information in background, on another thread
                    new AsyncTask<ApiConnector, Long, Boolean>() {
                        @Override
                        protected Boolean doInBackground(ApiConnector... apiConnectors) {
                            return apiConnectors[0].uploadImageToserver(nameValuePairs);
                        }
                    }.execute(new ApiConnector());

                    //tell the user that it is registred
                    Toast.makeText(getBaseContext(), getString(R.string.registred), Toast.LENGTH_LONG).show();

                    pDialog.dismiss();
                    //change window to main
                    Intent mainIntent = new Intent(getBaseContext(), MainActivity.class);
                    startActivity(mainIntent);

                } catch (Exception e) {
                    Log.d("MainActivity", e.toString());
                }

            }
        }).start();


    } //Here ends onClick(View v)
});

Solution

  • There is no need to have a different thread. AsyncTask already works on different thread. Also you need to dismiss your dialog and start the new activity when your AsyncTask is finished.

    Try this

    btnSubmit.setOnClickListener(new View.OnClickListener() {
        InputStream is = null;
    
        @Override
        public void onClick(View v) {
            pDialog = ProgressDialog.show(AvvikelseActivity.this, "Registrerar", "Vänta");
            try {
                    Bitmap immage = null;
                    //preapare the image
                    immage = BitmapFactory.decodeFile(imgurl);
                    final int maxSize = 960;
                    int outWidth;
                    int outHeight;
                    int inWidth = immage.getWidth();
                    int inHeight = immage.getHeight();
                    if (inWidth > inHeight) {
                        outWidth = maxSize;
                        outHeight = (inHeight * maxSize) / inWidth;
                    } else {
                        outHeight = maxSize;
                        outWidth = (inWidth * maxSize) / inHeight;
                    }
                    Bitmap resizedBitmap = Bitmap.createScaledBitmap(immage, outWidth, outHeight, false);
                    //initiate string imagedata, which will be the string for the actual image
                    String imagedata = null;
                    //encode the image
                    imagedata = encodeTobase64(immage);
                    //Setting nameValuePairs
                    final List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
                    //adding the string variables
                    nameValuePairs.add(new BasicNameValuePair("reporter", reporter));
                    nameValuePairs.add(new BasicNameValuePair("department", department));
                    nameValuePairs.add(new BasicNameValuePair("errortype", errortype));
                    nameValuePairs.add(new BasicNameValuePair("title", title));
                    nameValuePairs.add(new BasicNameValuePair("description", description));
                    nameValuePairs.add(new BasicNameValuePair("percaution", percaution));
                    nameValuePairs.add(new BasicNameValuePair("imgurl", imgurl));
                    nameValuePairs.add(new BasicNameValuePair("dataset", dataset));
                    nameValuePairs.add(new BasicNameValuePair("image", imagedata));
                    nameValuePairs.add(new BasicNameValuePair("phoneid", android_id));
                    nameValuePairs.add(new BasicNameValuePair("typ", TAG_TYP));
                    //Task to upload the information in background, on another thread
                    new AsyncTask<ApiConnector, Long, Boolean>() {
                        @Override
                        protected Boolean doInBackground(ApiConnector... apiConnectors) {
                            return apiConnectors[0].uploadImageToserver(nameValuePairs);
                        }
    
                        @Override
                        protected void onPostExecute(Boolean result) {
                            //tell the user that it is registred
                            Toast.makeText(getBaseContext(), getString(R.string.registred), Toast.LENGTH_LONG).show();
                            pDialog.dismiss();
                            //change window to main
                            Intent mainIntent = new Intent(getBaseContext(), MainActivity.class);
                            startActivity(mainIntent);
                        }
                    }.execute(new ApiConnector());
                } catch (Exception e) {
                    Log.d("MainActivity", e.toString());
                }
            }
        } //Here ends onClick(View v)
    });
    

    But if you want to use a new thread then just add this to your AsyncTask and remove the code inside this method from outside.

    @Override
    protected void onPostExecute(Boolean result) {
        //tell the user that it is registred
        Toast.makeText(getBaseContext(), getString(R.string.registred), Toast.LENGTH_LONG).show();
        pDialog.dismiss();
        //change window to main
        Intent mainIntent = new Intent(getBaseContext(), MainActivity.class);
        startActivity(mainIntent);
    }