2012-01-19 7 views
8

私は同様の質問を参照しようとしましたが、何の助けもありませんでした。AsyncTaskからデータを返すAndroid

私のアンドロイドアプリでは、ユーザーが最近アクセスした最近の見積もりを実装する予定です。つまり、最近訪問したウェブページと似ています。沿って現在のシンボル

1)ユーザーはどのような企業のビューを開くたびに、はデータベース

2から、会社のシンボルをフェッチ)次に店舗:後

は、私は、次のよのステップですデータベース内のdateTimeを使用します。データベースからフェッチされたすべての記号について

3)、はそのcurrent value%Changeと表示会社名、現在の値と、リスト内の%変化を取得します。

クラスではpostExecuteメソッドでは戻り値の型がvoid以外であるという問題が発生します。

何か間違っていますか?

どのようなヘルプは人生節約になります!誰または何それが戻ってくるので

String[] rsym,rcmp,rchg; 
rdbM = new RecentDBManager(CompanyView.this); 
try { 
Calendar date1 = Calendar.getInstance(); 
SimpleDateFormat dateformatter = new SimpleDateFormat(
          "dd/MM/yyyy HH:mm:ss"); 

String currentdate = dateformatter.format(date1.getTime()); 

rdbM.openDB(); 

//STEP 1 
rsym = rdbM.getRecent_sym(); 

//STEP 2     
rdbM.setData(currentsymbol, currentdate); 

rdbM.closeDB(); 

} catch (Exception e) { 
throw new Error(" *** ERROR in DB Access *** "+ e.toString()); 
} 

//STEP 3 
     for(int i=0;i<rsym.length;i++) 
     { 
      DownloadRecentQuote quotetask = new DownloadRecentQuote(); 
      recentquotetask 
      .execute(new String[] { "http://abc.com/stockquote.aspx?id=" 
         + rsym[i] }); 

//CURRENT VALUE and %CHANGE which should be returned from ASyncTask class 

      rcmp[i]=valuearr[0]; 
      rchg[i]=valuearr[1]; 
      } 

      list1 = new ArrayList<HashMap<String, String>>(); 
      HashMap<String, String> addList1; 

      for (int i = 0; i < limit; i++) 
      { 
       addList1 = new HashMap<String, String>(); 
       addList1.put(RecentSym_COLUMN, rsym[i]); 
       addList1.put(RecentCMP_COLUMN, rcmp[i]); 
       addList1.put(RecentChg_COLUMN, rchg[i]); 

       list1.add(addList1); 

       RecentAdapter adapter1 = new RecentAdapter(
        CompanyView.this, CompanyView.this, list1); 
       listrecent.setAdapter(adapter1); 
      } 


private class DownloadRecentQuote extends AsyncTask<String, Void, String> { 
    /* Fetching data for RecentQuote information */ 
    @Override 
    protected String doInBackground(String... urls) { 
     String response = ""; 
     for (String url : urls) { 
      DefaultHttpClient client = new DefaultHttpClient(); 
      HttpGet httpGet = new HttpGet(url); 
      try { 
       HttpResponse execute = client.execute(httpGet); 
       InputStream content = execute.getEntity().getContent(); 

       BufferedReader buffer = new BufferedReader(
         new InputStreamReader(content)); 
       String s = ""; 
       while ((s = buffer.readLine()) != null) { 
        response += s; 
       } 

      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
     return response; 
    } 

    @Override 
    protected void onPostExecute(String result) { 

     arr1 = result.split("@"); 

     if (arr1[0].length() != 0) { 

      if (arr1[0].equals("1")) { 

       arr = arr1[1].split(";"); 

      //RETURN 2 STRINGS 
          String valuearr[]; 
       valuearr[0] = arr[3]; 
       valuearr[1] = arr[6].concat("%"); 
       //return valuearr; 
      } 
     } 
    } 
+0

あなたがBroadCasteReceiver http://developer.android.com/reference/android/content/BroadcastReceiverを使用する場合、それは良くなります.html ..それはあなたが意図を通してデータを渡すことができます。 – ngesh

答えて

8

postExecute()が値を返すことはできませんか? AsyncTaskがバックグラウンドで実行されているため、AsyncTaskを呼び出した元のメソッドはなくなりました。 AsyncTask.execute()がバックグラウンドで実行されているため、postExecute()は値を返すことができません。

代わりに、AsyncTaskはアクティビティやその他のオブジェクトへの参照を必要とするため、値をポストバックすることができます。あなたのコードでは、あなたのタスクが完了していないので、execute()を呼び出した後の行はそこにはありません。代わりに、updateSymbol(currentPrice、percentChange)というメソッドを作成し、その中のすべてのコードをexecute()で移動し、AsyncTaskでActivityへの参照を渡す必要があります。その後、onPostExecute()メソッドからupdateSymbol(currentPrice、percentChange)を呼び出します。

しかし、doInBackground()が実行されている間にアクティビティへの参照が破棄される可能性があり、postExecute()が実行されたときに結果が破棄されるかUIを更新しないように注意してください。たとえば、ユーザが自分の電話を回転させると、アクティビティが破棄されます。アクティビティが破棄された場合にAsyncTaskをキャンセルできるように、アクティビティ内のAsyncTaskへの参照を保持することをお勧めします。あなたのタスクは同じよう取り消された場合はチェックしAsyncTask.cancel()を呼び出すことができます。

public void postExecute(String result) { 
    if(!isCanceled()) { 
     // do your updating here 
     activity.setSymbol(result); 
    } 
} 

それはあなたが簡単に実行しているAsyncTasksを追跡できるように、すべての活動の基本クラスを作成することはとても簡単です:

public class BaseActivity extends Activity { 

    List<AsyncTask> runningTasks; 

    public void onStop() { 
     for(AsyncTask task : runningTasks) { 
      task.cancel(true); 
     } 
    } 

    public AsyncTask start(AsyncTask task) { 
     runningTasks.add(task); 
     return task; 
    } 

    public void done(AsyncTask task) { 
     runningTasks.remove(task); 
    } 
} 

いくつかのクイックポインタ。実行する必要はありません(新しいString [] {"blah" + blah})。 JavaのVarargsではこれを実行できます。 execute( "blah" + blah)。また、例外をキャッチし、実際に処理することなく継続します。あなたのアプリがそれらをキャッチして何かが本当に起こったときは難しく、何も起こらないかのように続行します。エラーが発生した場合は、ユーザーに何らかのフィードバックを提供し、そのプロセスの実行を停止することができます。停止し、ユーザーにエラーを表示し、次のことをさせる。キャッチブロックをメソッドの下部に移動します。

+0

Thnxほど。私はアンドロイドの開発には新しく、これを理解しようとしています。 **あなたのAsyncTaskで**あなたはActivity **への参照を渡す必要がありますか? – GAMA

+0

DownloadRecentQuote task = new DownloadRecentQuote(これは、アクティビティ内からこれを実行していると仮定します)。アクティビティでDownloadRecentQuoteを実行していない場合は、DownloadRecentQuoteインスタンスを作成しているインスタンスへの参照を渡してから、そこからUIを更新する方法を見つけ出すことができます。あなたがアクティビティでDownloadRecentQuoteを作成しているように見えるのは、アダプタでリスト変数が表示されているからです。 – chubbsondubs

3

AsyncTask.onPostExecute()は、AsyncTaskのdoInBackground()が実行され、実行結果が返された後に、何をしたいかを実行する場所です。これはベストプラクティスと考えるべきです。

AsyncTask()。execute()がUIスレッドから呼び出されたとき(このメソッドはUIスレッドから呼び出さなければならないことに注意してください)、Androidフレームワークはワーカースレッドを作成し、AsyncTask.doInBackground )をこのワーカースレッド上に作成します。この時点で(新しいAsyncTask()。execute())を呼び出した後、UIスレッドは新しいAsyncTask()。execute()の後でコードを実行し続けます。今は実行時に2つのスレッド(UIとワーカースレッド)が同時に実行されます。

しかし、AsyncTaskの実行結果はワーカースレッドからUIスレッドに戻されますか?

ワーカースレッド(doInBackground())が終了してUIスレッドに戻るポイントは、AysncTask.onPostExecute()です。このメソッドは、AsyncTaskが終了するとすぐにUIスレッドのフレームワークによって呼び出されることが保証されています。言い換えれば、実行時にAsyncTask.onPostExecute()がどこでいつ呼び出されるかは気にしません。将来的には最終的に呼び出されることを保証するだけです。これが、このメソッドが実行結果を返さない理由です。代わりに、実行結果がdoInBackground()の唯一のメソッドパラメータとして渡される必要があります。また

、AndroidのAPIはAsyncTask.get()、時間をコーディングにAsyncTaskの実行結果を返す方法を提供します:

MyAsyncTask myAsyncTask = new MyAsyncTask(); 

// This must be called from the UI thread: 
myAsyncTask.execute(); 

// Calling this will block UI thread execution: 
ExecutionResult result = myAsyncTask.get(); 

ベア心​​の中AsyncTask.getは()呼び出し側スレッドの実行をブロックすること、およびUIスレッドで呼び出すと、おそらくANR例外が発生します。 AsyncTask.get()を使用するペイロードで、UIスレッドで呼び出すと、AsyncTask(ワーカースレッド)をUIスレッドと同期して実行します(UIスレッドを待機させることによって)。要約すると、これは実行可能ですが推奨されません。ただ、今後の参考のため

+0

'myAsyncTask.get()'は、 'onPostExecute()'から計算されたデータを取得するだけなので、UIを長時間ブロックするとは思わない。 –

+0

14行目「未来」の部分を除いて、あなたの答えは完璧です。 –

1

、このポストは少し古いですので:

私はONSTART()メソッドとAsyncTaskのために別のクラスを持っているActivityクラスを作成しました。私のテストに基づいて、doInbackground()メソッドの後に結果がアクティビティに最初に送信され、その後、onPostExecute()が実行されます。これは、logcatに基づいて、最初に(サーバーによって送信された)最初の応答データを持っているため、この応答はアクティビティから再び表示され、最後にonPostExecute()のメッセージが表示されます。

活動のためのコード:

@Override 
    protected void onStart() { 
     super.onStart(); 
     String str = "***"; 
     if(isConnectedToInternet()){ 
      myAsyncTask.execute(); 

      try { 
       if(myAsyncTask.get()) 
        str = myAsyncTask.getResponseMsg(); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } catch (ExecutionException e) { 
       e.printStackTrace(); 
      } catch (CancellationException e) { 
       e.printStackTrace(); 
      } 
     } 
     Log.i("Data returned by server2:", str); 
    } 

AsyncTaskコード:

public class MyAsyncTask extends AsyncTask<Void, Void, Boolean> { 

    private URL url; 
    private HttpURLConnection conn; 
    private String strResponseMsg; 

    public MyAsyncTask(String url) throws MalformedURLException{ 
     this.url = new URL(url); 
    } 


    @Override 
    protected void onPreExecute() { 
     Log.i("Inside AsyncTask", "myAsyncTask is abut to start..."); 
    } 

    @Override 
    protected Boolean doInBackground(Void... params) { 
     boolean status = false; 

     try { 
      conn = (HttpURLConnection) url.openConnection(); 
      conn.setConnectTimeout(Manager.ConnTimeout); 
      conn.setReadTimeout(Manager.ReadTimeout); 

      int responseCode = conn.getResponseCode(); 
      Log.i("Connection oppened", "Response code is:" + responseCode); 
      if (responseCode == HttpURLConnection.HTTP_OK) { 
       BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream())); 
       if (in != null) { 
        StringBuilder strBuilder = new StringBuilder(); 
        // Read character by character    
        int ch = 0; 
        while ((ch = in.read()) != -1) 
         strBuilder.append((char) ch); 

        // Showing returned message 
        strResponseMsg = strBuilder.toString(); 
        Log.i("Data returned by server:", strResponseMsg); 

        status = true; 
       } 
       in.close(); 
      } 

     } catch (IOException e) { 
      e.printStackTrace(); 
     }  

     return status; 
    } 

    @Override 
    protected void onPostExecute(Boolean result) { 
     Log.i("Inside AsyncTask", "myAsyncTask finished its task. Returning data to caller..."); 
    } 

    public String getResponseMsg(){ 
     return strResponseMsg; 
    } 
}