0

私の活動では、2 つのバックグラウンド サービスを実行する必要があります。

主なバックグラウンド サービス:

class loadingTask extends AsyncTask<Void, Void,Void> {

      @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        pd = ProgressDialog.show(context, "", "Chargement en cours..", true, false);
        super.onPreExecute();
    }


    @Override
    protected void onPostExecute(Void result) {
         // TODO Auto-generated method stub
        super.onPostExecute(result);
        pd.dismiss();
    }

    ...

    @Override
    protected Void doInBackground(Void... params) {
        // TODO Auto-generated method stub
        getxml = Util.CallWebService("");
        return null;
    }
}

2 番目のバックグラウンド サービス。

class mloadingTask extends AsyncTask<String, Void, String> {

    protected String doInBackground(String... urls) {

        SAXHelper sh = null;
        try {
            sh = new SAXHelper(urls[0]);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        sh.parseContent("");
        return "";

    }

    protected void onPostExecute(String s) {
        pd.dismiss();

    }
}

私のonCreate()方法では、最初のバックグラウンドを呼び出したいと思います。ロードが完了すると、2 番目のバックグラウンド サービスが開始されます。私のバックグラウンド サービスの一部は次のとおりです。

AsyncTask<Void, Void,Void> loadTask = new loadingTask().execute();

    if(loadTask.getStatus()==AsyncTask.Status.FINISHED){

         new mloadingTask().execute(getxml);

         System.out.println("getxml: "+getxml);
    }

ただし、2 番目のバックグラウンド サービスは開始されないようです。私もプリントを取得していません。ステップを逃したか、Android が同じアクティビティで複数のバックグラウンド サービスを許可していないと思います。助けてください。

4

2 に答える 2

0

AsyncTask は、その名前が示すように非同期です。最初の AsyncTask の onPostExecute で 2 番目の AsyncTask を呼び出す必要があります

また

アクティビティで AsyncTask が終了するまでループして待機しますが、時間がかかる場合があり、Application Not Responding メッセージが表示される場合があります。

execute() メソッドを呼び出すとすぐに、loadTask.getStatus() という次のステートメントに制御が移ります。タスクが開始されたばかりなので、loadTask.getStatus() は FINISH を返さず、2 番目のタスクは実行されません。

于 2013-04-03T09:50:58.347 に答える
0
AsyncTask<Void, Void,Void> loadTask = new loadingTask().execute();

if(loadTask.getStatus()==AsyncTask.Status.FINISHED){

  new mloadingTask().execute(getxml);

  System.out.println("getxml: "+getxml);
}

if() ブロックが通過しない可能性は 99% です。最初に loadTask という名前の最初の asyncTask を実行し、それが終了したかどうかを確認した後、RIGHT を実行します。それまでに実際に終了する可能性はわずかです。

簡単なアプローチ:

非同期タスクを 1 つだけ使用します。asyncTask 1 を終了してから asyncTask 2 を起動したいとします。これは、1 つの asyncTask だけで両方の操作を実行するのとまったく同じです。

class loadingTask extends AsyncTask<Void, Void,Void> {

      @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        pd = ProgressDialog.show(context, "", "Chargement en cours..", true, false);
        super.onPreExecute();
    }


    @Override
    protected void onPostExecute(Void result) {
         // TODO Auto-generated method stub
        super.onPostExecute(result);
        pd.dismiss();
    }

    ...

    @Override
    protected Void doInBackground(Void... params) {
        // TODO Auto-generated method stub
        getxml = Util.CallWebService("");

        SAXHelper sh = null;
        try {
            sh = new SAXHelper(urls[0]);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        sh.parseContent("");
        return null;
    }
}

難しいアプローチ:

このようなことを解決する方法は(状況は異なりますが、そうすべきです)

1 つのメソッドでインターフェイスを作成します。例えば:

public interface OnDataChangedListner {
    void dataChanged(Class listener);
}

次に、どこか (私はリポジトリ クラスを使用します) にメソッドを記述して、OnDataChangedListener インターフェイスのリストに全体を追加および削除します。

private ArrayList<OnDataChangedListner> mOnDataChangedListners;

public void addOnDataChangedListner(OnDataChangedListner onDataChangedListner){
    synchronized (mOnDataChangedListners){
        mOnDataChangedListners.add(onDataChangedListner);
    }
}

public void removeOnDataChangedListner(OnDataChangedListner onyDataChangedListner){
    if (mOnDataChangedListners != null){
        synchronized (mOnDataChangedListners){
            for (Iterator<OnDataChangedListner> it = mOnDataChangedListners.iterator(); it.hasNext();) {
                OnDataChangedListner listener = it.next();
                if (listener .equals(onDataChangedListner))
                    it.remove();
            }
        }
    }
}

これはやり過ぎかもしれません。ただし、この例は、タスクの実行中に UI を更新するのに役立ちます。無料の追加!:))

上記のコードを配置したら、リスナー メソッドの追加と削除を定義したのと同じクラスに onDataChanged() メソッドを作成します。

そのコードでハンドラーを呼び出します

// Need handler for callbacks to the UI thread
final static Handler mHandler = new Handler();

// Create runnable for posting
final Runnable mNotifyDataChanged = new Runnable() {
    public void run() {
        if (mOnDataChangedListners != null){
            synchronized (mOnDataChangedListners){
                for (Iterator<OnDataChangedListner> it = mOnDataChangedListners.iterator(); it.hasNext();) {
                    OnDataChangedListner listener = it.next();
                    if (listener  != null)
                        listener.dataChanged(this.getClass());
                    else
                        it.remove();
                }
            }
        }
    }
};

/**
 * will notify registerred delegates on the main (UI) thread
 */
public void notifyDataChanged(){
    mHandler.post(mNotifyDataChanged);
}

わかりましたので、サンプル全体を配布することになりました。このコードをどこに配置するかはあなた次第です。しかし、notifyDataChanged() を呼び出すと、ハンドラーが起動され、このクラスの現在登録されているすべてのリスナーをループします。

次に、リスナーの datachanged メソッドを呼び出します。

これをすべて機能させるには、クラスにインターフェースを実装させるだけです

addOnDataChangedListener(this) を呼び出します。

インターフェイスで提供されるメソッドを実装します。

これは間違いなく最も簡単な方法ではないことに注意してください。あなたがやりたいことをする最も簡単な方法が何であるかわかりません。私は以前にそのような状況にあったことはありません。

ただし、実装されたメソッドで 2 番目のタスクを実行できます。動作するはず..

于 2013-04-03T10:06:13.597 に答える