Android ProgressDialog 不能与 AsyncTask 一起使用

Posted

技术标签:

【中文标题】Android ProgressDialog 不能与 AsyncTask 一起使用【英文标题】:Android ProgressDialog not working together with AsyncTask 【发布时间】:2015-11-20 09:43:11 【问题描述】:

我正在尝试在另一个线程上运行一个函数。不幸的是,它只是继续前进而没有解雇。如果我在 run 函数中没有它,则 Try catch 有效。我认为这可能是我在函数内部的 AsyncTask。

我也发现了这个错误

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

这是我的代码

    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)
);

【问题讨论】:

嗨,你能告诉我“encodeTobase64”吗? 【参考方案1】:

没有必要有不同的线程。 AsyncTask 已经在不同的线程上工作。您还需要在 AsyncTask 完成后关闭对话框并开始新活动。

试试这个

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)
);

但是,如果您想使用新线程,只需将其添加到您的 AsyncTask 并从外部删除此方法中的代码。

@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);

【讨论】:

@Rihit5k2 出于某种原因,onPostExecute 上的 Override 变为红色。有什么线索吗? 方法不会覆盖其超类中的方法 我的错误。只需将onPostExecute的参数类型改为boolean protected void onPostExecute(boolean result) 像这样?它仍然不起作用? OnPostExecute 应该有 Override 吗? @Rohit5k2 是的,只需更改参数即可。它可以与我们一起使用而无需覆盖。我个人选择保留它。【参考方案2】:

你需要使用这个

           runOnUiThread(new Runnable() 
                @Override
                public void run() 
                    pDialog.dismiss();
                
            );

而不是普通的pDialog.dismiss();

对 Ui 的任何更新都必须从 Ui 线程或主线程进行。

【讨论】:

以上是关于Android ProgressDialog 不能与 AsyncTask 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

Android:ProgressDialog.show() 使用 getApplicationContext 崩溃

Xamarin.Android:ProgressDialog 不显示

Android:ProgressDialog 不显示

Android 强制关闭 ProgressDialog

使用自定义 ProgressDialog android

Android 进度条对话框ProgressDialog