簡體   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