如何等到线程在android中完成

时间:2017-03-29 01:25:37

标签: java android multithreading

我有这个方法updatePosts()需要在一个线程内运行。看起来像这样

public void updatePosts(){
    new Thread(){
        public void run(){
            posts.addAll(pholder.fetchPosts());
            System.out.println("size of posts is " + posts.size());

            // UI elements should be accessed only in
            // the primary thread, so we must use the
            // handler here.

        }
    }.start();
}

它实际上更新名为" posts"的列表。我在onCreate中有这个。问题是,因为它在一个单独的线程中运行,所以在我的ImageAdapter需要使用" posts"之前它没有完成。列表。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    updatePosts();
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    GridView gridview = (GridView) findViewById(R.id.gridview);
    gridview.setAdapter(new ImageAdapter(this, posts));

    gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v,
                                int position, long id) {
            Toast.makeText(MainActivity.this, "" + position,
                    Toast.LENGTH_SHORT).show();
        }
    });

}

我有哪些选项可以确保在创建ImageAdapter之前updatePosts可以完成?

2 个答案:

答案 0 :(得分:1)

您应该使用AsyncTask或任何其他机制,允许您将任务卸载到后台线程,并在完成时回调UI。

.SILENT:

另一种选择是使用RxJava,

private class BackgroundTask extends AsyncTask<Void, Void, List<Post>> {

    @Override
    protected List<Post> doInBackground(Void... params) {
        // TODO
        return posts;
    }

    @Override
    protected void onPostExecute(List<Post> posts) {
        // TODO: update UI
    }
}

答案 1 :(得分:0)

我认为你需要使用Handler。

private ImageAdapter mAdapter;
private MyHandler mHandler;
private List<YourData> posts;
@Override 
protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
 setSupportActionBar(toolbar);

 GridView gridview = (GridView) findViewById(R.id.gridview);
 mAdapter = new ImageAdapter(this, posts);
 gridview.setAdapter(mAdapter);
 gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View v,
                            int position, long id) {
        Toast.makeText(MainActivity.this, "" + position,
                Toast.LENGTH_SHORT).show();
    } 
 }); 
 mHandler = new MyHandler(this);
 updatePosts();
}
public void updatePosts(){ 
new Thread(){
    public void run(){ 
        posts.addAll(pholder.fetchPosts()); 
        System.out.println("size of posts is " + posts.size());
        if (mHandler != null) {
          mHandler.sendMessage(mHandler.obtainMessage(1));
         }
        // UI elements should be accessed only in 
        // the primary thread, so we must use the 
        // handler here. 

    } 
}.start();
}
private static class MyHandler extend Handler{
 private WeakReference<Your Activity name> outer;
 public MyHandler(Your Activity name activity){
     outer = new WeakReference<>(activity);
 }
 @Override
 public void handleMessage(Message msg){
     switch(msg.what){
         case 1:
             if(outer.get()!=null){
                 outer.get().mAdapter.refresh(outer.get().posts);
             }
         break;
         default:break;
     }
 }
}

在ImageAdapter中,您需要添加一个方法:

 public void refresh(List<YourData> dataSet){
  this.dataSet = dataSet;
  notifyDataSetChanged();
}