安卓开发 - 利用 Handler 在子线程执行 IO 操作后修改 UI

在安卓开发的过程中,耗时的 IO 操作要放在子线程中执行,以免阻塞 UI ,而 UI 操作要在 UI 线程中执行,以免出现冲突的问题,那么如何在进行 IO 操作后对 UI 进行修改呢?于是到了 Handler 出场的时候了...

例子

仅作演示,我们的操作很简单,就是点击一个 Button 时用 HttpURLConnection 获取本站 (http://conw.net) 的源代码并显示在一个 EditText 中。
简单起见,我就不写 XML 代码了,仅用 Java 代码,如下:

package net.conw.viewsource;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ///绘制 UI
        LinearLayout layout = new LinearLayout(this);
        layout.setOrientation(LinearLayout.VERTICAL);

        Button button = new Button(this);
        button.setText("View Source");
        final EditText editText = new EditText(this);

        layout.addView(button);
        layout.addView(editText);

        setContentView(layout);

        ///这里加final关键字是因为 Java 中只有这样才能在匿名内部类中访问
        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                editText.setText((String) msg.obj);
            }
        };

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ///在新的线程执行网络请求
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            URL url = new URL("http://conw.net");
                            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                            connection.connect();
                            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                            String line, html = "";
                            while ((line = in.readLine()) != null)
                                html += line + "\n";
                            ///创建一个Message
                            Message message = new Message();
                            message.obj = html;
                            handler.sendMessage(message);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        });

    }
}

另外别忘了在 AndroidManifest.xml 文件中的加上获取网络权限的代码:

<uses-permission android:name="android.permission.INTERNET" />

这行代码要放在 <manifest> 标签内、 <application> 标签外才行。这样不出意外的话,我们点击按钮的时候,就能获取到本站的源代码了。

关于代码中的几个地方:
1、关于 Java IO 操作的介绍,请看这里:还没写
2、Handler 的对象是用 final 声明的,具体原因请看这篇文章:还没写
3、代码中用 Http Get 请求获取获取了本站的源代码,使用了 HttpURLConnection ,这是在安卓开发中推荐使用的, Java 中一般使用 HttpURLConnection ,更多的细节请看这里:还没写

Handler的使用
handler 通常在 UI 线程中创建,然后重写他的 handleMessage() 方法修改UI。子线程获取到主线程的 handler 对象(可以简单通过一个 setHandler() 方法),然后子线程中只需要执行 handler.sendMessage(message) 即可。
Message
这里的 message 是一个 Message 对象,你可以为它的 int arg1int arg2Object obj 绑定一些对象,然后一起发送出去,如果数据比较复杂的话,还可以用 setData() 方法为之绑定一个 Bundlemessage 发送出去后,handlerhandleMessage() 方法就会执行了。

标签: android

已有 3 条评论

  1. 有个东西叫 runOnUIThread --

添加新评论