繁体   English   中英

如何在单独的线程中管理进度对话框? 无法在未调用Looper.prepare()的线程内创建处理程序

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

首先,有两个不同的异步类,分别称为AsyncMySqlInsertCallSoap,而我在AsyncMySqlInsert中使用CallSoap。

其次,他们每个人都有进度对话框。 如果它们彼此独立运行,则可以毫无例外地显示进度对话框。 但是,如果它们一起运行,则会发生一个名为java.lang.RuntimeException的异常:无法在尚未调用Looper.prepare()的线程内创建处理程序 那么如何在单独的线程中管理进度对话框?

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

堆栈跟踪

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)

您可以在UI线程中创建其他线程可以访问的Handler。 他们发布到此处理程序( handler.run(Runnable) )的所有Runnable都会堆栈到UI消息队列中。

或者,您可以将消息循环与任何一个线程Looper.prepare()然后在其中使用处理程序。( Looper.prepare() )。 您可以在这里看到一个示例。

除了UI线程之外,您不能在任何其他对象上构造AsyncTask。 您将必须更改要在UI线程上构造并传递到AsyncMySqlInsert的CallSoap异步任务。 从那里,也许您可​​以在您的CallSoap异步任务上有一个setter方法,您的MySql任务将调用该方法(因为看来您需要在CallSoap任务内部的MySql任务中提供值)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM