• Android中更新UI的三种方式


    置顶 Android_葱 2019-04-07 14:57:40 4695 收藏 18
    分类专栏: Android 文章标签: Android UI 线程 AsyncTask Handler
    版权

    Android
    专栏收录该内容
    7 篇文章0 订阅
    订阅专栏
    Android中更新UI的三种方式:
    1.在工作线程中更新UI
    2.使用AsyncTask
    3.使用Handler

    本博客的界面用的同一个xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
    android:id="@+id/hello_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!" />

    <Button
    android:id="@+id/change_btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Change"
    android:textAllCaps="false"/>

    </LinearLayout>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    1.在工作线程中更新
    在上一篇博客中,我写到工作线程中不能对UI控件进行操作,但最后提到了(Android系统提供了一些工具用于在工作线程中更新主线程)
    (1)使用View的postInvalidate()方法刷新页面
    (2)使用Activity的runOnUiThread()方法更新UI
    (3)使用View的post()和postDelayed()方法更新UI

    public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final TextView tv = (TextView) findViewById(R.id.hello_text);
    Button bt = (Button) findViewById(R.id.change_btn);

    final ExecutorService mThreadPool = Executors.newCachedThreadPool();
    bt.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    mThreadPool.execute(new Runnable() {
    @Override
    public void run() {
    //刷新界面
    // tv.postInvalidate();

    //使用Activity的runOnUiThread()方法更新UI
    // MainActivity.this.runOnUiThread(new Runnable() {
    // @Override
    // public void run() {
    // tv.setText("OH,I am Fine!!!");
    // }
    // });

    //使用View的post()方法更新UI
    // tv.post(new Runnable() {
    // @Override
    // public void run() {
    // tv.setText("Hi,Fresh By Post");
    // }
    // });

    //使用View的postDelayed()方法更新UI
    tv.postDelayed(new Runnable() {
    @Override
    public void run() {
    tv.setText("Hi,Fresh By postDelayed :");
    }
    },1000);
    }
    });
    }
    });
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    2.使用AsyncTask
    AsyncTask是Android给我们提供的一种轻量级的异步任务类
    我们做一个点击按钮后,demo会进行10s的倒计时
    我们重写了doInBackground()后,剩下5个回调方法,他们也是AsyncTask中的生命周期方法,我们在相应的方法中进行初始化,赋值等操作。(下面的代码中有详细的备注)

    MainActivity.java

    public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button bt = (Button) findViewById(R.id.change_btn);

    final ExecutorService mThreadPool = Executors.newCachedThreadPool();
    bt.setOnClickListener(new View.OnClickListener() {
    MyAsyncTask myAsyncTask;
    @Override
    public void onClick(View v) {
    myAsyncTask = new MyAsyncTask();
    myAsyncTask.execute(Long.valueOf("10"));
    }
    });
    }

    class MyAsyncTask extends AsyncTask<Object,String,String>{

    TextView tv;

    @Override
    protected void onPreExecute() {
    tv = (TextView) findViewById(R.id.hello_text);

    tv.setText("倒计时开始!");
    }

    /**
    * doInBackground()方法是必须重写的一个方法
    * 唯一的一个运行在工作线程中的方法
    * 用来执行在工作线程中要执行的任务
    */
    @SuppressLint("WrongThread")
    @Override
    protected String doInBackground(Object... objects) {
    if (objects.length == 1 && objects[0] instanceof Long){
    Long inputTime = (Long) objects[0];
    for (;inputTime > 0;inputTime--){
    publishProgress(inputTime + "s"); //传给onProgressUpdate()的参数
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }else{
    //这里用到了上面的线程中更新UI的方法,不是AsyncTask更新UI的方法
    MainActivity.this.runOnUiThread(new Runnable() {
    @Override
    public void run() {
    tv.setText("倒计时失败");
    }
    });
    cancel(true);
    }
    return null;
    }

    /**
    * onProgressUpdate()方法是运行在主线程中的方法
    * 所以我们在这里可以直接对UI进行更新
    *
    * 我们下面获取的values是上面publishProgress传的参数
    * (本demo中只有一个String类型的参数)
    */
    @Override
    protected void onProgressUpdate(String... values) {
    tv.setText(values[0]);
    }

    /**
    * onPostExecute()方法是doInBackground()方法执行完毕后执行的方法
    */
    @Override
    protected void onPostExecute(String s) {
    tv.setText("倒计时完毕");
    }

    /**
    * 取消时的回调方法
    */
    @Override
    protected void onCancelled(String s) {
    super.onCancelled(s);
    }
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    效果截图:
    3.使用Handler更新UI
    Handler是Android消息机制的上层接口。Handler是专门用来在线程之间传递消息的工具类,主要用于UI界面的更新,消息的传递与处理。
    Handler发送消息的两种方法:
    1.send系列方法:用于发送一个包含数据的Message对象,并在handleMessage(Message message)方法中处理。(下面demo使用的方法)
    2.post系列的方法:用于发送一个Runnable对象,并在MessageQueue收到消息时执行。

    public class MainActivity extends AppCompatActivity {

    private static final int CHANGE = 1;
    private TextView tv;

    private final MyHandle handle = new MyHandle();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button bt = (Button) findViewById(R.id.change_btn);
    tv = (TextView) findViewById(R.id.hello_text);

    bt.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    new Thread(new Runnable() {
    @Override
    public void run() {
    Message ms = new Message();
    ms.what = CHANGE;
    handle.sendMessage(ms);
    }
    }).start();
    }
    });
    }

    class MyHandle extends Handler{
    @Override
    public void handleMessage(Message msg) {
    super.handleMessage(msg);
    switch (msg.what) {
    case CHANGE:
    tv.setText("hello, Changed by Handle!!!");
    break;
    default:
    break;
    }
    }
    }
    }
    ————————————————
    版权声明:本文为CSDN博主「Android_葱」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/weixin_39936201/article/details/89063607

    https://blog.csdn.net/weixin_39936201/article/details/89063607

  • 相关阅读:
    javascript与XML
    错误调试
    Js节点操作
    vue渲染时对象里面的对象的属性提示undefined,但渲染成功
    html5脚本编程
    用canvas把页面中所有元素的轮廓绘制出来
    HTTP的三次握手
    http协议的发展历史
    5层网络模型介绍
    http主要内容流程介绍
  • 原文地址:https://www.cnblogs.com/pengmn/p/15548897.html
Copyright © 2020-2023  润新知