How can I manage progress dialogs in separate threads? Can't create handler inside thread that has not called Looper.prepare()

风流意气都作罢 提交于 2019-12-25 02:21:37

问题


Firstly there are 2 different asynch classes called AsyncMySqlInsert and CallSoap and I am using CallSoap in AsyncMySqlInsert.

Secondly each one of them has progressdialog. They can display their progressdialogs without exception if they run separate from each other. But if they run together an exception called java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() occurs. So how can I manage progress dialogs in separate threads?

    class AsyncMySqlInsert extends AsyncTask<Object, String, Void> {
    protected ProgressDialog progressDialog;
    private Context context;

    public AsyncMySqlInsert(Context context, String activityName) {
        this.context = context;
    }

    @Override
    protected void onPreExecute() {
        progressDialog = ProgressDialog.show(context, "Kayıtlar içeri alınıyor...", "Bu işlem birkaç dakika sürebilir, lütfen bekleyin.", true, true);
    }

    @Override
    protected Void doInBackground(Object... params) {
        DataTable filteredDt = (DataTable)params[0];
        DataTable dtSonuc = new DataTable(Gonderim.this);
        String sql="";
        int rowID = 0;
        dtSonuc.setColumns(new String[]{"rowid","success"});

        for (int i = 0; i < filteredDt.getCount(); i++) {
            Object[] newRow = new Object[2]; //2 kolonlu ROWID | SUCCESS
            rowID = Integer.parseInt(filteredDt.getValueByColumnName(i, "RowID"));
            newRow[0] = String.valueOf(rowID);
            sql = filteredDt.getValueByColumnName(i, "MySql");
            try {
                GenelSql.getInstance(Gonderim.this).execSql(sql);
                newRow[1] = "true";
            } catch (Exception e) {
                newRow[1] = "false";
                Log.e("Mysql Hata: ", e.getMessage() + " " + sql);
            }
            dtSonuc.insert(newRow, dtSonuc.getCount() < 0 ? 0 : dtSonuc.getCount());
            publishProgress("Kayıtlar içeriye alınıyor (" + String.valueOf(i) + " / " + filteredDt.getCount() + ")");
        }

        DataSet ds = new DataSet(Gonderim.this);
        ds.add(dtSonuc);
        setMethodName("KsmMysqlUpdDelForAndroid");  
        Hashtable<String, Object> parameters = new Hashtable<String, Object>();
        parameters.put("ds", ds);
        parameters.put("Rep", txtRep);
        CallSoap soap = new CallSoap(Gonderim.this, uri_test, soapAction, parameters);
        //Log.e("KsmMysqlUpdDelForAndroid", "Mysql'den bana gelen satırları işledim, geriye dogru execute edilen ve edilmeyenleri ayırdığım bir dataset ile geri yolluyorum.");


        soap.execute(""); 
        soap.setDataDownloadListener(new CallSoap.DataDownloadListener() {
            public void dataDownloadedSuccessfully(final String xdata) {

            }
            public void dataDownloadFailed() {
            }
        });


        return null;
    }

    @Override
    protected void onProgressUpdate(String... values) {
        progressDialog.setMessage(values[0]);
        super.onProgressUpdate(values);
    }

    @Override
     protected void onPostExecute(Void result) {
         progressDialog.dismiss(); 
         getDonen();
     }
 }

STACK TRACE

12-05 18:57:34.110: E/AndroidRuntime(31467): FATAL EXCEPTION: AsyncTask #5
12-05 18:57:34.110: E/AndroidRuntime(31467): java.lang.RuntimeException: An error occured while executing doInBackground()
12-05 18:57:34.110: E/AndroidRuntime(31467):    at android.os.AsyncTask$3.done(AsyncTask.java:266)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1081)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:574)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at java.lang.Thread.run(Thread.java:1020)
12-05 18:57:34.110: E/AndroidRuntime(31467): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
12-05 18:57:34.110: E/AndroidRuntime(31467):    at android.os.Handler.<init>(Handler.java:121)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at android.app.Dialog.<init>(Dialog.java:100)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at android.app.AlertDialog.<init>(AlertDialog.java:96)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at android.app.AlertDialog.<init>(AlertDialog.java:80)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at android.app.ProgressDialog.<init>(ProgressDialog.java:76)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at android.app.ProgressDialog.show(ProgressDialog.java:109)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at android.app.ProgressDialog.show(ProgressDialog.java:103)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at com.quadro.main.Util.CallSoap.onPreExecute(CallSoap.java:201)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:549)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at android.os.AsyncTask.execute(AsyncTask.java:499)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at com.quadro.main.Gonderim$AsyncMySqlInsert.doInBackground(Gonderim.java:751)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at com.quadro.main.Gonderim$AsyncMySqlInsert.doInBackground(Gonderim.java:1)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at android.os.AsyncTask$2.call(AsyncTask.java:252)
12-05 18:57:34.110: E/AndroidRuntime(31467):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
12-05 18:57:34.110: E/AndroidRuntime(31467):    ... 4 more
12-05 18:57:34.590: E/WindowManager(31467): Activity com.quadro.main.Gonderim has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40ac56f0 that was originally added here
12-05 18:57:34.590: E/WindowManager(31467): android.view.WindowLeaked: Activity com.quadro.main.Gonderim has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@40ac56f0 that was originally added here
12-05 18:57:34.590: E/WindowManager(31467):     at android.view.ViewRoot.<init>(ViewRoot.java:288)
12-05 18:57:34.590: E/WindowManager(31467):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:249)
12-05 18:57:34.590: E/WindowManager(31467):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:193)
12-05 18:57:34.590: E/WindowManager(31467):     at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:118)
12-05 18:57:34.590: E/WindowManager(31467):     at android.view.Window$LocalWindowManager.addView(Window.java:532)
12-05 18:57:34.590: E/WindowManager(31467):     at android.app.Dialog.show(Dialog.java:269)
12-05 18:57:34.590: E/WindowManager(31467):     at android.app.ProgressDialog.show(ProgressDialog.java:115)
12-05 18:57:34.590: E/WindowManager(31467):     at android.app.ProgressDialog.show(ProgressDialog.java:103)
12-05 18:57:34.590: E/WindowManager(31467):     at com.quadro.main.Gonderim$AsyncMySqlInsert.onPreExecute(Gonderim.java:716)
12-05 18:57:34.590: E/WindowManager(31467):     at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:549)
12-05 18:57:34.590: E/WindowManager(31467):     at com.quadro.main.Gonderim$7.dataDownloadedSuccessfully(Gonderim.java:394)
12-05 18:57:34.590: E/WindowManager(31467):     at com.quadro.main.Util.CallSoap.onPostExecute(CallSoap.java:246)
12-05 18:57:34.590: E/WindowManager(31467):     at com.quadro.main.Util.CallSoap.onPostExecute(CallSoap.java:1)
12-05 18:57:34.590: E/WindowManager(31467):     at android.os.AsyncTask.finish(AsyncTask.java:590)
12-05 18:57:34.590: E/WindowManager(31467):     at android.os.AsyncTask.access$600(AsyncTask.java:149)
12-05 18:57:34.590: E/WindowManager(31467):     at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:603)
12-05 18:57:34.590: E/WindowManager(31467):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-05 18:57:34.590: E/WindowManager(31467):     at android.os.Looper.loop(Looper.java:132)
12-05 18:57:34.590: E/WindowManager(31467):     at android.app.ActivityThread.main(ActivityThread.java:4123)
12-05 18:57:34.590: E/WindowManager(31467):     at java.lang.reflect.Method.invokeNative(Native Method)
12-05 18:57:34.590: E/WindowManager(31467):     at java.lang.reflect.Method.invoke(Method.java:491)
12-05 18:57:34.590: E/WindowManager(31467):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
12-05 18:57:34.590: E/WindowManager(31467):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
12-05 18:57:34.590: E/WindowManager(31467):     at dalvik.system.NativeStart.main(Native Method)

回答1:


You can create a Handler in the UI thread which other threads can access. Any Runnable they post to this handler (handler.run(Runnable)) will the stack onto the UI message queue.

Or you could assosiate a message loop with either thread and use handlers there.(Looper.prepare()). You can see an example of this here.




回答2:


You can't construct an AsyncTask on anything but the UI Thread. You are going to have to change your CallSoap async task to be constructed on the UI thread and passed into your AsyncMySqlInsert. From there, maybe you could have a setter method on your CallSoap async task that your MySql task will call (since it appears you need values from your MySql task inside of the CallSoap task).



来源:https://stackoverflow.com/questions/8388808/how-can-i-manage-progress-dialogs-in-separate-threads-cant-create-handler-insi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!