[英]How can I manage progress dialogs in separate threads? Can't create handler inside thread that has not called Looper.prepare()
Firstly there are 2 different asynch classes called AsyncMySqlInsert and CallSoap and I am using CallSoap in AsyncMySqlInsert. 首先,有两个不同的异步类,分别称为AsyncMySqlInsert和CallSoap,而我在AsyncMySqlInsert中使用CallSoap。
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.
但是,如果它们一起运行,则会发生一个名为java.lang.RuntimeException的异常:无法在尚未调用Looper.prepare()的线程内创建处理程序 。 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();
}
}
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)
You can create a Handler in the UI thread which other threads can access. 您可以在UI线程中创建其他线程可以访问的Handler。 Any Runnable they post to this handler (
handler.run(Runnable)
) will the stack onto the UI message queue. 他们发布到此处理程序(
handler.run(Runnable)
)的所有Runnable都会堆栈到UI消息队列中。
Or you could assosiate a message loop with either thread and use handlers there.( Looper.prepare()
). 或者,您可以将消息循环与任何一个线程
Looper.prepare()
然后在其中使用处理程序。( Looper.prepare()
)。 You can see an example of this here . 您可以在这里看到一个示例。
You can't construct an AsyncTask on anything but the UI Thread. 除了UI线程之外,您不能在任何其他对象上构造AsyncTask。 You are going to have to change your CallSoap async task to be constructed on the UI thread and passed into your AsyncMySqlInsert.
您将必须更改要在UI线程上构造并传递到AsyncMySqlInsert的CallSoap异步任务。 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).
从那里,也许您可以在您的CallSoap异步任务上有一个setter方法,您的MySql任务将调用该方法(因为看来您需要在CallSoap任务内部的MySql任务中提供值)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.