在我的应用程序中,我正在从一个单独的类中使用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();
在上面的代码中,以下Toast出现在AsyncTAsk中Toast出现之前,问题是,如何暂停我的主线程等待AsyncTAsk完成。 非常感谢:)
答案 0 :(得分:3)
我建议您阅读有关Context
Android
的不同类型的this解释。有些Context
的实例不允许您执行其他Context
个实例所做的某些事情(即Service
是Context
,不允许布局膨胀) 。
在您的情况下,您将Application
Context
传递给AsyncTask
构造函数,然后传递给Dialog
。您应该使用Activity
Context
代替。
由于您从AsyncTask
拨打Activity
并从Activity
延伸Context
,因此您可以使用this
中的关键字AsyncTask
像Cata这样的实例化。
答案 1 :(得分:2)
除了使用正确的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();
}
....
答案 2 :(得分:1)
我建议两件事:
WeakReference
AsyncTask
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
的背景。
答案 3 :(得分:0)
试试这个:
fileexist = new Utilssss(this).execute("http://192.168.1.2/eWorldLiterature/urdu/index.txt").get();
其中“this”应该是Activity并且假设参数代表Utilssssclass一侧的mContext:)。
并且也要关注Emmanuel的答案。