Android SDK AsyncTask doInBackgroundが実行されていない(サブクラス)



Answers

この回答をチェックアウトする必要があります: https://stackoverflow.com/a/10406894/347565 : https://stackoverflow.com/a/10406894/347565とそれに含まれるGoogleグループへのリンク。

私はあなたと同じような問題を抱えていましたが、なぜそれが機能していないのかはっきりしていませんが、私のコードをこのように変更して、

ASyncTask<Void,Void,Void> my_task = new ASyncTask<Void,Void,Void>() { ... };
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
    my_task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null);
else
    my_task.execute((Void[])null);
Question

2015年2月15日現在、私はまだ良い説明を見つけていないし、これがうまくいかない理由も見つけていない。 ソリューションに最も近いのは、伝統的なThreadアプローチを使用することですが、なぜAndroid SDKで動作しないクラスが含まれているのでしょうか?

イブンイン!

私はAsyncTaskサブクラスを持っています:

// ParseListener had a callback which was called when an item was parsed in a
// RSS-xml, but as stated further down it is not used at all right now.
private class xmlAsync extends AsyncTask<String, RSSItem, Void> implements ParseListener

これは次のように実行されます:

xmlAsync xmlThread = new xmlAsync();

xmlThread.execute("http://www.nothing.com");

このサブクラスでは少しエラーが発生しました。 以前はxml-parsingを行っていましたが、 doInBackground()が呼び出されていないことに気がついたとき、私はそれを一行ずつ取り除き 、ついにこれで終わりました:

@Override
protected Void doInBackground(String... params) 
{
    Log.v(TAG, "doInBackground");
        return null;
}

なんらかの理由で、何も記録されませんでした。 しかし、私はこれを追加しました:

@Override
protected void onPreExecute() 
{
        Log.v(TAG, "onPreExecute");
        super.onPreExecute();
}

スレッドを実行すると、その行が実際に記録されます。 だから何とかonPreExecute()は呼び出されますが、doInBackground()は呼び出されません 。 私は別のAsyncTaskをバックグラウンドで実行しており、同時にうまく動作します。

私は現在、エミュレータ、SDKバージョン15、Eclipse、Mac OS X 10.7.2で北極に近いところでアプリケーションを実行しています。

編集:

@Override
    protected void onProgressUpdate(RSSItem... values) {

        if(values[0] == null)
        {
                            // activity function which merely creates a dialog
            showInputError();
        }
        else
        {

            Log.v(TAG, "adding "+values[0].toString());
            _tableManager.addRSSItem(values[0]);
        }


        super.onProgressUpdate(values);
    }

_tableManager.addRSSItem()多かれ少なかれ、アクティビティのコンテキストで初期化されたSQLiteDatabaseに行を追加します。 publishProgress()は、Interface ParseListenerのコールバックによって呼び出されます。 しかし、私はdoInBackground()でlog.vを除いて何もしないので、最初にこれを起動する必要はないことがわかりました。

編集2:

さて、完全にはっきりするために、これは他のAsyncTaskであり、同じアクティビティで実行され、完全に正常に動作します。

private class dbAsync extends AsyncTask<Void, RSSItem, Void>
{
    Integer prevCount;
    boolean run;

    @Override
    protected void onPreExecute() {
        run = true;
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... params) {
        // TODO Auto-generated method stub
        run = true;
        prevCount = 0;

        while(run)
        {
            ArrayList<RSSItem> items = _tableManager.getAllItems();

            if(items != null)
            {
                if(items.size() > prevCount)
                {
                    Log.v("db Thread", "Found new item(s)!");
                    prevCount = items.size();

                    RSSItem[] itemsArray = new RSSItem[items.size()];

                    publishProgress(items.toArray(itemsArray));
                }
            }               

            SystemClock.sleep(5000);
        }

        return null;
    }

    @Override
    protected void onProgressUpdate(RSSItem... values) {

        ArrayList<RSSItem> list = new ArrayList<RSSItem>();

        for(int i = 0; i < values.length; i++)
        {
            list.add(i, values[i]);
        }

        setItemsAndUpdateList(list);

        super.onProgressUpdate(values);
    }

    @Override
    protected void onCancelled() {
        run = false;

        super.onCancelled();
    }
}

編集3:

一口、すみません、私は質問するのが悪いです。 しかし、ここでタスクの初期化があります。

xmlAsync _xmlParseThread;
dbAsync _dbLookup;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

_dbLookup = new dbAsync();
_dbLookup.execute();

_xmlParseThread = new xmlAsync();       
_xmlParseThread.execute("http://www.nothing.com", null);
}



Androidは残酷です! 私はこれを信じることができません。 ある日、その1つのスレッド、次に5つのスレッド、もう1つは128スレッドです。

とにかくここにAsyncTask株の代わりにほとんどドロップされています。 必要に応じてAsyncTaskを呼び出すこともできますが、混乱を避けるため、ThreadedAsyncTaskという名前を付けます。 execute()は最終的なのでexecuteの代わりにexecuteStart()を呼び出す必要があります。

/**
 * @author Kevin Kowalewski
 *
 */
public abstract class ThreadedAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> { 
    public AsyncTask<Params, Progress, Result> executeStart(Params... params){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
            return executePostHoneycomb(params);
        }else{
            return super.execute(params);
        }
    }


    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private AsyncTask<Params, Progress, Result> executePostHoneycomb(Params... params){
        return super.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params); 
    }
}



あなたがクラスのインスタンスをインスタンス化してexecute()メソッドを呼び出す場所はどこですか? AsyncTaskのドキュメントを読んだら、両方の操作をメインのUIスレッドで行う必要があります。 オブジェクトを作成して他のスレッドからexecuteを呼び出すと、onPreExecuteが起動するかもしれませんが、私は100%確実ではありませんが、バックグラウンドスレッドは作成されず実行されません。

AsyncTaskのインスタンスをバックグラウンドスレッドから作成する場合や、メインのUIスレッドで行われていないその他の操作を行う場合は、このメソッドの使用を検討することができます: Activity.runOnUiThread(Runnable)

そのメソッドを呼び出すには、実行中のアクティビティのインスタンスにアクセスする必要がありますが、UIスレッドで実行されていない他のコードからUIスレッドでコードを実行することができます。

希望は意味をなさない。 私がもっと助けることができるかどうか教えてください。

デビッド




私はそのsdkだと思う。 私は同じ問題を抱えていました。目標のSDTを15から11に変更した後、すべてが完全に機能します。

sdk15では、AsyncTask.StatusがRUNNINGであっても、doInBackgroundは決して呼び出されません。 私はそれがUIのスレッドとは何か関係があると思う。




Links