当逐渐深入学习android的时候,会不可避免接触到网络开发的.

有时我们需要从网络上获取大量数据时,获取完数据后,会及时进行主线程UI的更新,如果把这些耗时的操作放到主UI线程时,可能会造成主线程阻塞以致应用程序关闭,这时我们就需要把这些耗时的操作单独的放到另外的线程中,确保主线程能正常的运行.在android当中,一般能实现这些效果的有两种方法,一种是Handler,另外一种是AsyncTask.

今天我们就主要讲讲Handler的使用方法,就以从我们学校新闻网上获取新闻内容为例,为了方便大家能清晰快速的了解Handler,我就从网上获取少量的数据,闲话少说,我就先给大家看看代码与实现效果:

import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import org.jsoup.Jsoup;import org.jsoup.nodes.Document;import org.jsoup.nodes.Element;import org.jsoup.select.Elements;import android.app.Activity;import android.app.ProgressDialog;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.util.Log;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;public class MainActivity extends Activity {    private TextView data;    private Button start;    private Handler handler;    private ProgressDialog progressDialog = null;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        data = (TextView) findViewById(R.id.data);        start = (Button) findViewById(R.id.start);        handler = new Handler() {            public void handleMessage(Message msg) {                // progressDialog.dismiss();                Log.i("5", "第三个");                String content = (String) msg.obj;                data.setText(content);                start.setText("结束");            };        };        start.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View arg0) {                Log.i("1", "第一个");                progressDialog = new ProgressDialog(getApplicationContext());                progressDialog.setMessage("正在登录...");                progressDialog.setCancelable(false);                // progressDialog.show();                login();            }        });    }    protected void login() {        new Thread(new Runnable() {            @Override            public void run() {                try {                    Log.i("2", "第二");                    Document doc = Jsoup.connect(                            "http://www.cnwust.com/index.html").get();                    List<Map<String, String>> list = new ArrayList<Map<String, String>>();                    Elements elements = doc.select("#inner_nav a");                    Log.i("3", elements.toString());                    for (int i = 1; i < elements.size(); i++) {                        Map<String, String> map = new HashMap<String, String>();                        map.put("title", elements.get(i).text());                        map.put("link", elements.get(i).attr("abs:href"));                        list.add(map);                    }                    Log.i("4", list.toString());                    handler.obtainMessage(1, list.get(1).get("title"))                            .sendToTarget();                } catch (IOException e) {                    e.printStackTrace();                }            }        }).start();    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.main, menu);        return true;    }}

对应的布局文件代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" >    <LinearLayout  android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" >        <TextView  android:id="@+id/data" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" android:text="测试数据" android:textSize="15dp" />        <Button  android:id="@+id/start" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="10dip" android:text="开始" />    </LinearLayout></RelativeLayout>

实现的效果:

让我们来分析分析这段程序代码是怎么运行的,它首先是在主activity里面申明了一个Handler,然后在主进程创建之后进行实例化,并且在里面写了handlerMessage的方法,对接收到的Message进行处理,并实现对主UI线程的更新,注意在更新主界面UI的操作只能放到这个里面,其余地方可能系统会报错.
我们已经实现了对接受到了的Message的处理,接下来我们来看看我们应该在什么时候选择发送消息呢,由于消息里面一般都会包含我们从网络上获取到的数据,所以当我们新建一个新线程,在里面进行耗时操作完后,我们可以把我们得到的数据,装载到Message里面,并且发送到Handler里面,注意这里面的方法
handler.obtainMessage(1, list.get(1).get(“title”)).sendToTarget().
方法当从的第一个参数”1”,对应的是Message的What,实质就是个int型数据,它的使用,是为了方便我们对接收到的数据进行一个分析,如果我们从网络上获取数据时,我们可以用”0”来表示获取数据失败,用”1”来表示成功,我们再在handlerMessage方法里面写个switch语句处理就行了,由于笔者比较偷懒,就没有在这份代码中写了╯﹏╰,,,,, 而第二个参数list.get(1).get(“title”)它的值其实是个String类型的数据,它对应的是Message的Object,由于String是继承了的Object的,所以系统不会报错,对于这个object的类,我们一般在里面放置从网络获取得到的数据.准备好Message后,我们一定要注意在后面加上一个sendtoTarget()的方法,不然Handler不能得到消息,,,,,而这个Message也遵循一个队列的机制,先进先出,它是逐个逐个发送的,如果读者想要在这方面深究的话,可以了解了解下面这些博客

Android Handler机制

Android消息队列及线程机制详解

完成这些操作后,我们基本上算是对Handler有个大致的了解了,关于实现多线程更新UI的第二个方法,本人会在之后的博客里再给大家介绍.

以上是笔者在实践中对Handler的理解,由于个人的技术水平有限,某些观点可能有些不当,还希望各位路过的大牛能够批评指正!!!

更多相关文章

  1. 一句话锁定MySQL数据占用元凶
  2. [置顶] Android之路——第一个上线 APP项目总结
  3. Python+PyQT5的子线程更新UI界面
  4. 微信授权APP第三方登陆(Android)
  5. android 数据库处理及操作
  6. Android高性能编码 - 第二篇 数据库操作
  7. 一切为了更贴近系统―Android中的线程模型
  8. Android(安卓)程序应该考虑的问题
  9. Android与PHP交互,Android传递JSON数据,PHP接受并保存数据

随机推荐

  1. Android代码开发性能指引
  2. android 2.3 截屏总结
  3. 运用smali自动注入技术分析android应用程
  4. Androdi设置透明度及透明度对应的色值
  5. [Android(安卓)实例] 史上最全的Android
  6. Android中多线程同步问题
  7. android阿里面试java基础锦集
  8. 移动端app开发-02-iPhone/iPad/Android U
  9. Android Framework启动流程浅析
  10. Android内核开发:理解和掌握repo工具