[英]How to show spinning progress dialogue with using separate Async Task Class
在我的应用程序中,我正在使用Async Tasking从一个单独的类中从Web服务器读取文本文件,因为它在许多活动中都使用过,所以我做了一个专门的类。 我正在尝试显示旋转进度对话框,但是当我将代码放入Async Tasking类时却给了我错误。
这是我异步任务班的鳕鱼
public class Utilssss extends AsyncTask<String, String, String> {
private Context mContext;
private ProgressDialog pdia;
// constructor
public Utilssss(Context activityContext) {
mContext = activityContext;
}
protected void onPreExecute() {
super.onPreExecute();
pdia = new ProgressDialog(mContext);
pdia.setMessage("Loading...");
pdia.show();
}
protected String doInBackground(String... url) {
return GetLinkss(url[0]);
}
protected void onPostExecute(String result) {
// Toast.makeText(mContext, result, Toast.LENGTH_LONG).show();
super.onPostExecute(result);
pdia.dismiss();
}
private String GetLinkss(String url) {
// your stuff
String StringBuffer = "";
String stringText = "";
try {
URL link = new URL(url);
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(link.openStream()));
while ((StringBuffer = bufferReader.readLine()) != null) {
stringText += StringBuffer;
}
bufferReader.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return stringText;
}
}
编码我如何上这堂课
public void urdu(View view) throws InterruptedException, ExecutionException {
String fileexist = null;
fileexist = new Utilssss(getBaseContext()).execute("http://192.168.1.2/eWorldLiterature/urdu/index.txt").get();
Toast.makeText(getBaseContext(), fileexist, Toast.LENGTH_SHORT).show();
// if (fileexist != 229) {
Intent i = new Intent(getBaseContext(), MainPage.class);
i.putExtra(LANGUAGE, "urdu");
startActivity(i);
这是LogCat结果。
12-05 00:38:06.266: E/AndroidRuntime(28766): FATAL EXCEPTION: main
12-05 00:38:06.266: E/AndroidRuntime(28766): java.lang.IllegalStateException: Could not execute method of the activity
12-05 00:38:06.266: E/AndroidRuntime(28766): at android.view.View$1.onClick(View.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at android.view.View.performClick(View.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at android.view.View$PerformClick.run(View.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at android.os.Handler.handleCallback(Handler.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at android.os.Handler.dispatchMessage(Handler.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at android.os.Looper.loop(Looper.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at android.app.ActivityThread.main(ActivityThread.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at java.lang.reflect.Method.invokeNative(Native Method)
12-05 00:38:06.266: E/AndroidRuntime(28766): at java.lang.reflect.Method.invoke(Method.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at dalvik.system.NativeStart.main(Native Method)
12-05 00:38:06.266: E/AndroidRuntime(28766): Caused by: java.lang.reflect.InvocationTargetException
12-05 00:38:06.266: E/AndroidRuntime(28766): at java.lang.reflect.Method.invokeNative(Native Method)
12-05 00:38:06.266: E/AndroidRuntime(28766): at java.lang.reflect.Method.invoke(Method.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): ... 12 more
12-05 00:38:06.266: E/AndroidRuntime(28766): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
12-05 00:38:06.266: E/AndroidRuntime(28766): at android.view.ViewRootImpl.setView(ViewRootImpl.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at android.app.Dialog.show(Dialog.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at md.literature.imranseries.Utilssss.onPreExecute(Utilssss.java:35)
12-05 00:38:06.266: E/AndroidRuntime(28766): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at android.os.AsyncTask.execute(AsyncTask.java)
12-05 00:38:06.266: E/AndroidRuntime(28766): at md.literature.imranseries.Selection.urdu(Selection.java:65)
12-05 00:38:06.266: E/AndroidRuntime(28766): ... 14 more
我还想问一件事。 抱歉,再次打扰您。.事情在这里,我的活动之一依赖于Asynctask的结果,除非任务完成,否则不应该继续进行,但是这种情况没有发生,这里有一段代码证明了这一点。
final Context context = this;
new Utils(context, new Utils.UtilsCallback() {
@Override
public void onResult(String lstr) {
// lstr = string;
Toast.makeText(getBaseContext(), "Now Raeading" + Novelselected, Toast.LENGTH_LONG).show();
}
}).execute(ulti_link + "/" + Novelselected.replace(" ", "%20") + ".txt");
Toast.makeText(getBaseContext(), "Now Raeading", Toast.LENGTH_LONG).show();
在上面的代码中,在AsyncTAsk中的Toast出现之前,以下Toast出现了,问题是,我如何暂停我的主线程以等待AsyncTAsk完成。 非常感谢 :)
我建议你阅读此有关不同类型的解释Context
Android
了。 有些Context
实例不允许您做某些其他Context
实例可以做的事情(即Service
是不允许布局膨胀的Context
)。
在您的情况下,您要将Application
Context
传递给AsyncTask
构造函数,然后传递给Dialog
。 您应该改为使用Activity
Context
。
由于您是从Activity
调用AsyncTask
,而Activity
从Context
扩展的,因此您可以在AsyncTask
实例化中使用关键字this
,如Cata所说。
除了使用正确的Context
您不得使用AsyncTask#get()
。 决不。 它会阻塞Ui线程,直到结果可用,并且在那期间您无法显示进度对话框,因为您已经在等待结果。
如果要使用其他类中的AsyncTask,请添加自己的回调机制。
public class Utilssss extends AsyncTask<String, String, String> {
/** Implement this somewhere to get the result */
public interface UtilssssCallback {
void onResult(String string);
}
private Context mContext;
private ProgressDialog pdia;
private UtilssssCallback mListener;
// constructor
public Utilssss(Context activityContext, UtilssssCallback listener) {
mContext = activityContext;
mListener = listener; // save callback
}
@Override
protected void onPostExecute(String result) {
pdia.dismiss();
mListener.onResult(result);
}
// rest omitted since unchanged
}
在你的Activity
public void urdu(View view) {
final Context context = this;
new Utilssss(context, new Utilssss.UtilssssCallback() {
@Override
public void onResult(String string) {
Toast.makeText(context, string, Toast.LENGTH_LONG).show();
Intent i = new Intent(context, MainPage.class);
i.putExtra(LANGUAGE, "urdu");
context.startActivity(i);
}
}).execute("http://192.168.1.2/eWorldLiterature/urdu/index.txt");
}
请注意, onResult
内部的代码是在程序流已经离开urdu(View view)
方法之后执行的。
除了将回调实现为匿名内部类( new UtilssssCallback(){...}
)之外,您还可以让Activity
实现接口并将其作为方法。 以这种方式进行操作看起来不太混乱,但本质上是相同的。
public class TheActivity extends FragmentActivity implements UtilssssCallback {
public void urdu(View view) {
// those two are not necessary but help make it obvious what parameters we have
Context context = this;
UtilssssCallback callback = this; // the class implements that
new Utilssss(context, callback).execute("http://192.168.1.2/eWorldLiterature/urdu/index.txt");
}
@Override
public void onResult(String string) {
Toast.makeText(context, string, Toast.LENGTH_LONG).show();
}
....
我建议两件事:
AsyncTask
时使用WeakReference
Activity
上调用方法以启动和停止进度对话框 像这样:
public class ProgressAsyncTask extends AsyncTask<Void, Void, Void> {
private WeakReference<Activity> weakActivity;
public ProgressAsyncTask(Activity activity) {
weakActivity = new WeakReference<Activity>(activity);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
Activity activity = weakActivity.get();
((MainActivity) activity).showProgressDialog(true);
}
@Override
protected void doInBackground(Void... params) {
// Do stuff
}
@Override
protected void onPostExecute(List<Color> result) {
super.onPostExecute(result);
Activity activity = weakActivity.get();
((MainActivity) activity).showProgressDialog(false);
}
在您的MainActivity中,实现方法showProgressDialog(boolean show)
。
正如伊曼纽尔(Emmanuel)指出的那样,您最有可能应该传递Activity
的上下文。
尝试这个:
fileexist = new Utilssss(this).execute("http://192.168.1.2/eWorldLiterature/urdu/index.txt").get();
其中“ this”应为Activity,并假定参数代表Utilssssclass端的mContext :)。
并且也要注意伊曼纽尔的回答。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.