2012-11-26 330 views
1

我正在做我的第一個android應用程序。在其中一頁上,我需要使用REST服務連接到Drupal站點,檢索一些數據(視頻URL列表,它們的標題,描述等)並將其顯示在列表中。當我點擊列表時,我會轉到視頻的細節。等待異步任務完成

這是我想要繼續。 1°從Drupal站點獲取所有數據。 2°點擊列表中的某個項目時,將該視頻的詳細信息傳遞給下一個活動。

問題是這樣的: 當連接到Android 3+的互聯網時,你不能在主線程上這樣做,所以我不得不使用AsyncTask來獲取數據。這工作,但然後我想將視頻保存在ArrayList中,然後使用getVideos()或getVideo(index)函數訪問該列表。第一個填充列表,第二個在進入細節活動之前檢索數據。問題是,當我嘗試訪問視頻列表時,該列表尚未填充。

從技術上講,我並不真的需要/想要使用asynctask,但在主線程上連接到互聯網會引發錯誤,說它不是正確的做事方式。

這裏是我如何獲得錄像的簡化版本:

public class VideoDaoImpl { 
     private List<Video> videos ; 

     public VideoDaoImpl(){ 
      videos = new ArrayList<Video>(); 
      new VideoTask(...).execute(); //fetch the videos in json format and 
      //call function onRemoteVideoCallComplete using a handler 
      //in the onPostExecute() function of the asyncTask 
     } 

     public List<Video> getVideos() { 
      return videos; 
     } 

     public Video getVideo(int index){ 
      return videos.get(index); 
     } 

     public onRemoteVideoCallComplete(JSONObject json) { 
      //transform Json into videos and add them to the videos arraylist 
     } 

    } 

這是我要填寫我的活動視頻列表:

public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_videos_list); 
     //get all videos (not yet filled since faster than second thread) 
     List<Video> videos = videoDao.getVideos(); 
     //get a list of all the titles to display as the list 
     List<String> formattedVideos = VideoHelper.formatVideosList(videos); 

     ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
       android.R.layout.simple_list_item_1, formattedVideos); 

     ListView listView = (ListView) findViewById(R.id.videos_list); 
     listView.setAdapter(adapter); 
     listView.setOnItemClickListener(new VideosListItemClickListener(this)); 
    } 

所以,真正的問題是這樣的。有沒有更好的方法來解決這個問題,或者有沒有辦法等待列表被填充。

回答

2

我會保持AsyncTask,因爲它,但我會考慮使用onPostExecute()。在onPostExecute()裏面,我會將你的Json轉換成視頻對象列表,然後從中創建格式化視頻列表。然後你可以調用一個方法將格式化視頻列表傳回給你的活動,然後設置列表。

例如您的異步內:

protected void onPostExecute(Json result) { 
    //Create list of videos from json 
    //Create formatted list 
    //call method in activity to set list e.g activity.setList(formatted List) 
} 
+0

我最終選擇了這個解決方案(除了我不在postExecute中執行它,而是使用一個處理程序返回到VideoDaoImpl類)。 – Vilcoyote

+0

另外,Android Query可能會讓人感興趣,它的工作原理非常簡單,太糟糕了,後來我發現它太晚了:http://code.google.com/p/android-query/ – Vilcoyote

0

使用您的方法會使預期行爲成爲您所面對的行爲,即視頻列表尚未填充。您正在使用的assynchronous的方法,但同步思維處理問題,你知道的,根據您的評論「尚未填補,因爲比第二個線程更快」

videoDao.getVideos(); 

應該在你的onPostExecute方法被調用,或之後。我會做這樣的事,認爲它是一個草案,而不是一個完整的解決方案。

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_videos_list); 
    new VideoTask(...).execute(); // you should a use a something on your onPreExecute() inside this task showing a ProgressDialog so the user knows that something is "loading videos, please wait" 

    List<Video> videos = videoDao.getVideos(); 
    if (!videos.isEmtpy()) { 
     //get a list of all the titles to display as the list 
     List<String> formattedVideos = VideoHelper.formatVideosList(videos); 

     ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
      android.R.layout.simple_list_item_1, formattedVideos); 

     ListView listView = (ListView) findViewById(R.id.videos_list); 
     listView.setAdapter(adapter); 
     listView.setOnItemClickListener(new VideosListItemClickListener(this)); 
    } 
} 

基本上它顯示的區別是你可以從你的VideoDAO中提取你的AsyncTask。使用ProgressDialog執行它以通知事件正在進行,然後檢查視頻列表是否已填充。如果是,請在您的videos_list上顯示視頻。當然,這只是一個粗略的草案,但我認爲你可以明白。

+0

嘿,感謝回答。這並不是我所看到的,因爲videoDao的全部目的都是爲了獲得視頻列表。我只是不想讓它成爲填充活動列表視圖的人,因爲我想要分離獲取視頻(面向數據)和填充列表(面向UI)的任務。由於時間上的原因,我最終還是這樣做了。 – Vilcoyote