2014-02-08 126 views
0

我試圖在將我的活動轉換爲片段後,在片段中執行異步任務。當我從活動中調用異步任務時,我必須通過「this」來允許異步任務在收到信息後更改文本和事物。我有點困惑如何做到這一切都與片段。以下是我走到這一步:執行片段中的異步任務

我與執行asynck任務:

new GetYourTopTasteBeers(this).execute(url); 

的異步任務的代碼是:

public class GetYourTopTasteBeers extends AsyncTask<String, Void, String> { 

    Context c; 
    private ProgressDialog Dialog; 

    public GetYourTopTasteBeers (Context context) 
    { 
     c = context; 
     Dialog = new ProgressDialog(c); 
    } 

    @Override 
    protected String doInBackground(String... arg0) { 
     // TODO Auto-generated method stub 
     return readJSONFeed(arg0[0]); 
    } 

    protected void onPreExecute() { 
     Dialog.setMessage("Getting beers"); 

     Dialog.setTitle("Loading"); 
     Dialog.setCancelable(false); 
     Dialog.show(); 
    } 

    protected void onPostExecute(String result){ 
     //decode json here 
     try{ 
      JSONArray jsonArray = new JSONArray(result); 


      //acces listview 
      ListView lv = (ListView) ((Activity) c).findViewById(R.id.topTasteBeers); 

      //make array list for beer 
      final List<ShortBeerInfo> tasteList = new ArrayList<ShortBeerInfo>(); 



      for(int i = 0; i < jsonArray.length(); i++) { 

       String beer = jsonArray.getJSONObject(i).getString("beer"); 
       String rate = jsonArray.getJSONObject(i).getString("rate"); 
       String beerID = jsonArray.getJSONObject(i).getString("id"); 
       String breweryID = jsonArray.getJSONObject(i).getString("breweryID"); 


       int count = i + 1; 

       beer = count + ". " + beer; 


       //create object 
       ShortBeerInfo tempTaste = new ShortBeerInfo(beer, rate, beerID , breweryID); 

       //add to arraylist 
       tasteList.add(tempTaste); 


       //add items to listview 
       ShortBeerInfoAdapter adapter1 = new ShortBeerInfoAdapter(c ,R.layout.brewer_stats_listview, tasteList); 
       lv.setAdapter(adapter1); 

       //set up clicks 
       lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
        @Override 
        public void onItemClick(AdapterView<?> arg0, View arg1, 
              int arg2, long arg3) { 
         ShortBeerInfo o=(ShortBeerInfo)arg0.getItemAtPosition(arg2); 

         String tempID = o.id; 
         String tempBrewID = o.brewery; 

         Toast toast = Toast.makeText(c, tempID, Toast.LENGTH_SHORT); 
         toast.show(); 

         //todo: change fragment to beer page 

         Intent myIntent = new Intent(c, BeerPage2.class); 
         myIntent.putExtra("id", tempID); 
         myIntent.putExtra("breweryID", tempBrewID); 
         c.startActivity(myIntent); 


        } 
       }); 




      } 

     } 
     catch(Exception e){ 

     } 

     Dialog.dismiss(); 

    } 

    public String readJSONFeed(String URL) { 
     StringBuilder stringBuilder = new StringBuilder(); 
     HttpClient httpClient = new DefaultHttpClient(); 
     HttpGet httpGet = new HttpGet(URL); 
     try { 
      HttpResponse response = httpClient.execute(httpGet); 
      StatusLine statusLine = response.getStatusLine(); 
      int statusCode = statusLine.getStatusCode(); 
      if (statusCode == 200) { 
       HttpEntity entity = response.getEntity(); 
       InputStream inputStream = entity.getContent(); 
       BufferedReader reader = new BufferedReader(
         new InputStreamReader(inputStream)); 
       String line; 
       while ((line = reader.readLine()) != null) { 
        stringBuilder.append(line); 
       } 
       inputStream.close(); 
      } else { 
       Log.d("JSON", "Failed to download file"); 
      } 
     } catch (Exception e) { 
      Log.d("readJSONFeed", e.getLocalizedMessage()); 
     } 
     return stringBuilder.toString(); 
    } 

} 

我的問題是,我不能通過「這種從一個片段...

獎勵題:

而且你可以看到,我沒有做轉換我的代碼片段。我需要改變這個加載一個片段,而不是更改活動:

//todo: change fragment to beer page 
         Intent myIntent = new Intent(c, BeerPage2.class); 
         myIntent.putExtra("id", tempID); 
         myIntent.putExtra("breweryID", tempBrewID); 
         c.startActivity(myIntent); 

如何傳遞片段之間的值,就像我的活動之間在上面的代碼在做什麼?

回答

1

您無法通過this,因爲在這種情況下this引用了您的片段,該片段不延伸Context。但是,你需要Context(您GetYourTopTasteBeers需要Context作爲參數):

public GetYourTopTasteBeers (Context context) 

相反,通過你的Activity像這樣:

new GetYourTopTasteBeers(getActivity()).execute(url); 
2

由於Fragment■不要承認this,您可致電getActivity()代替這將提供執行AsyncTask所需的上下文。

要小心,雖然,作爲運行AsyncTask一個Fragment內可能會導致一個結果返回到已在您的AsyncTask結束其進程的時間破壞了呼叫者Activity。有必要採取額外的預防措施,並始終檢查Fragment是否尚未銷燬。這可以使用Fragment中的​​3210完成。

一個好的做法是在onStop()onPause()方法中取消您的AsyncTask。如果Fragment不再活動(getActivity()將返回null),那麼onPostExecute()將不會執行代碼。

+0

在onStop()中取消你的'AsyncTask'確實是一個好習慣。但不要在'onPause()'中做。執行'onPause()'後,活動仍然存在,所以不需要取消。 –

+0

如果有任何風險在該暫停中更新,應該停止。然而,即使它暫停了,你也可能需要它運行(例如,一個TCP套接字) – nKn