android中的痛苦线程

时间:2012-05-11 19:11:42

标签: android

我的预期结果是在第一次启动时会显示一个进度对话框,等待后台线程加载内容。在工作线程完成工作后,对话框解除。我做了搜索并得到了这个解决方案How to display progress dialog before starting an activity in Android?

这是我的完整代码:

    private ManagerApplication app;
    private ImageAdapter adapter;
    private GridView gridview;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        setupView();      
    }

    private void setupView() {
        gridview = (GridView) findViewById(R.id.gridview);
        app = (ManagerApplication) getApplication();
        ProgressDialog progress = new ProgressDialog(this);
        progress.setMessage("Loading...");
        new LoadImageTask(progress, this).execute();       
    }

    private class LoadImageTask extends AsyncTask<Void, Void, Void> {
        private ProgressDialog progress;
        private Context context;

        public LoadImageTask(ProgressDialog progress, Context context) {
            this.progress = progress;
            this.context = context;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progress.show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            adapter = new ImageAdapter(app.getShoes(), context);
            gridview.setAdapter(adapter); 
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            progress.dismiss();
        }

    }

但是,我的应用程序崩溃的原因是“只有创建视图层次结构的原始线程才能触及其视图”。我认为有一些东西阻止了主UI线程,但它仍然非常不清楚。所以有人能指出我的问题吗?感谢

2 个答案:

答案 0 :(得分:5)

有趣的是,你应该阅读一篇名为Painless Threading的文章。您不应该尝试在doInBackground中操纵视图。在您的情况下,您可以调用app.getShoes()但不要在那里进行适配器设置。

答案 1 :(得分:2)

  

doinBackground是非UI线程,所以永远不要更新任何UI(View)   方法...

并使用OnPostExecute or OnProgressUpdate for update UI

 @Override
        protected Void doInBackground(Void... params) {
           //here just background task ,
     //its non UI Thread so dont set ant view here set it in OnPostExecute,...
            return null;
        }

从setupview调用asynctask

private void setupView() {
        gridview = (GridView) findViewById(R.id.gridview);
        app = (ManagerApplication) getApplication();

        new LoadImageTask(progress, this).execute();       
  }

并在OnPreExecute method

中创建ProgressDilog
ProgressDialog progress;

@Override
    protected void onPreExecute() {
        super.onPreExecute();

     progress = new ProgressDialog(this);
     progress.setMessage("Loading...");
     progress.show();
    }

并在onPostExecute dismiss it