zoukankan      html  css  js  c++  java
  • Android 关于操作UI线程

    在非UI线程里访问 Android UI toolkit—这个在一个worker线程修改了 View 。这会导致不可预期的结果,而且还难以调试。

    为了修复这个问题,Android提供了几个方法从非UI线程访问Android UI toolkit 。详见下面的这个列表:

    可以使用 View.post(Runnable) 方法来修改之前的代码:

    public void onClick(View v){
        new Thread(new Runnable(){
            public void run(){
                final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
                mImageView.post(new Runnable(){
                    public void run(){
                        mImageView.setImageBitmap(bitmap);
                    }
                });
            }
        }).start();}
    

      

    现在这个方案的线程安全的:这个网络操作在独立线程中完成后,UI线程便会对ImageView 进行操作。

    使用 AsyncTask

    AsyncTask 能让你在UI上进行异步操作。它在一个worker线程里进行一些阻塞操作然后把结果交给UI主线程,在这个过程中不需要你对线程或者handler进行处理。

    使用它,你必须继承 AsyncTask 并实现 doInBackground() 回调方法,这个方法运行在一个后台线程池里面。如果你需要更新UI,那么你应该实现onPostExecute()这个方法从 doInBackground() 取出结果,然后在 UI 线程里面运行,所以你可以安全的更新你的UI。你可以通过在UI线程调用 execute()方法来运行这个任务。

    比如,你可以通过使用 AsyncTask来实现之前的例子:

    public void onClick(View v){
        new DownloadImageTask().execute("http://example.com/image.png");
    }
    private class DownloadImageTask extends AsyncTask<String,Void,Bitmap>{
        /** The system calls this to perform work in a worker thread and
          * delivers it the parameters given to AsyncTask.execute() */
        protected Bitmap doInBackground(String... urls){
            return loadImageFromNetwork(urls[0]);
        }
        
        /** The system calls this to perform work in the UI thread and delivers
          * the result from doInBackground() */
        protected void onPostExecute(Bitmap result){
            mImageView.setImageBitmap(result);
        }}
    

      

    现在UI是安全的了,代码也更加简单了,因为AsyncTask把worker线程里做的事和UI线程里要做的事分开了。

    你应该阅读一下 AsyncTask 的参考文档以便更好的使用它。下面就是一个对 AsyncTask 如何作用的快速的总览:

    注意: 你在使用worker线程的时候可能会碰到的另一个问题就是因为runtime configuration change (比如用户改变了屏幕的方向)导致你的activity不可预期的重启,这可能会kill掉你的worker线程。为了解决这个问题你可以参考 Shelves 这个项目。

    线程安全的方法

    在某些情况下,你实现的方法可能会被多个线程所调用,因此你必须把它写出线程安全的。

    转自:http://greenrobot.me/devpost/android-thread-and-process/

  • 相关阅读:
    Python split()方法分割字符串
    Python创建线程
    Python find()方法
    webpack中‘vant’全局引入和按需引入【vue-cli】
    webpack中‘mint-ui’全局引入和按需引入【vue-cli】
    nginx中 处理post方式打开页面的报错405
    nginx中 vue路由去掉#后的配置问题
    webpack中 VUE使用搜狐ip库查询设备ip地址
    webpack中 VUE使用百度地图获取地理位置
    VUE动态设置网页head中的title
  • 原文地址:https://www.cnblogs.com/spring87/p/4881606.html
Copyright © 2011-2022 走看看