2012-11-26 337 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