1

我正在做我的第一个安卓应用程序。在其中一个页面上,我需要使用 REST 服务连接到 Drupal 站点,检索一些数据(视频 url 列表、标题、描述等)并将其显示在列表中。当我单击列表时,我会转到视频的详细信息。

这就是我想继续的方式。1° 从 drupal 站点获取所有数据。2° 单击列表中的某个项目时,将该视频的详细信息传递给下一个活动。

问题是:在 android 3+ 中连接到互联网时,您无法在主线程上执行此操作,因此我不得不使用 AsyncTask 来获取数据。这行得通,但是我想将视频保存在 ArrayList 中,然后使用 getVideos() 或 getVideo(index) 函数访问该列表。第一个填充列表,第二个在进入详细信息活动之前检索数据。问题是当我尝试访问视频列表时该列表尚未填充。

从技术上讲,我真的不需要/不想使用异步任务,但是在主线程上连接到互联网会引发错误,说明这不是正确的做事方式。

这是我如何获取视频的简化版本:

    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));
    }

所以问题真的是这个。有没有更好的方法来解决这个问题,或者有没有办法等待列表被填满。

4

2 回答 2

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)
 }
于 2012-11-26T15:47:01.103 回答
0

使用您的方法会使预期的行为成为您面临的行为,即视频列表尚未填充。您正在使用异步方法处理问题,但同步思考,并且您知道这一点,基于您的评论“尚未填充,因为比第二个线程快”

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 执行它以告知正在发生的事情,然后检查视频列表是否已填满。如果是,请在您的视频列表中显示视频。当然这只是一个粗略的草稿,但我想你可以理解。

于 2012-11-26T15:29:00.890 回答