繁体   English   中英

如何使用单独的异步任务类显示旋转进度对话框

[英]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 ,而ActivityContext扩展的,因此您可以在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();
    }

....

我建议两件事:

  1. 将上下文传递到AsyncTask时使用WeakReference
  2. 在“ 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.

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