异步操作之handler+message<一>

转发请注明出处:http://blog.csdn.net/qq_28055429/article/details/51941385

一,Handler:

(1)解释:处理者,即消息传递机制

(2)基本方法:

 void handleMessage(Message msg):处理消息,经常使用此方法

Message obtainMessage():获取消息


以下几个方法均以final boolean 开头:

sendEmptyMessage(int what):发送空消息

sendEmptyMessageDelayed(int what , long delayMills):指定多少毫秒后发送空消息

 sendMessage(Message msg):立即发送消息 ,常用此方法

sendMessageDelayed(Message msg , long delayMillis):指定多少毫秒后发送消息

 hasMessages(int what):检查消息队列中是否包含what属性为指定值的消息

 hasMessages(int what , Object object):检查消息队列中是否包含属性值what,object属性为指定对象的消息


(3)两个常用作用:

----在新启动的线程中发送消息

------在主线程中获取,处理消息

(4)相关联:Message,Loop,MessageQueue,

Message:Handler接收和处理的消息对象,其相关参数有:

--- arg1和arg2 :用来存放整型数据的;

----- what :用来保存消息标示的;

-----  obj :是Object类型的任意对象;

-----  replyTo :是消息管理器,会关联到一个handler

Looper :每个线程只能有一个Looper,其loop方法负责读取MessageQueue中的消息,然后发给Handler处理

MessageQueue:消息队列,采用先进先出来存储管理Message


二,Handler和Message的一般处理步骤(Loop ,MessageQueue暂时不探讨)

(1)创建Handler对象,可以采用继承Handler的方法,也可以采用new Handler方法,如下:

   public class ImageHandle extends Handler{};

  或  private Handler handler = new Handler(){}

(2)重写其handleMessage(Message msg)方法,根据传回来的Message对象去处理

(3)在需要的地方,创建Message对象,并设置其相关参数,再调用handler.sendMessage(message)发送消息给Handler处理

  如:

Message message = new Message();
        message.what = i ;
        handler.sendMessage(message);

(4)然后handler就去处理了,,

三,3个例子:


例子(1):从网络上加载图片,然后显示出来:

布局文件:activity_third:采用ScrollView布局,放置一个LinearLayout(里面放置3个ImageView,用于显示网上图片)

<?xml version="1.0" encoding="utf-8"?>
<!--定义页面的基本布局:滚动布局-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!--在滚动布局中加入线性布局-->
    <LinearLayout
        android:id="@+id/layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center_horizontal"
        android:background="@color/skyblue"
        android:orientation="vertical">
        <!--加入图片控件1和3-->
        <ImageView
            android:id="@+id/Iv1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <ImageView
            android:id="@+id/Iv2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <ImageView
            android:id="@+id/Iv3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>

</ScrollView>


异步类:ImageHandle:继承自Handler,重写hanldeMessage方法,在里面执行相关操作,代码如下:

package testsdcard.com.maiyu.s04_71.activity.handle;

import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.media.Image;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;

import java.net.URL;

/**
 * Created by maiyu on 2016/7/16.
 */
public class ImageHandle extends Handler {
    Activity context ;  //定义Activity的上下文对象

    public ImageHandle(Activity context){
        this.context = context;
    }

    //接收thread发送过来的mesage信息
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        //从message信息中得到从网络请求下来的图片信息,并设置到imageView对象上
        ImageView img = (ImageView)context.findViewById(msg.arg1);
        img.setImageDrawable((Drawable)msg.obj);
    }

    //读取网络图片的函数,第一个参数为网络图片的url,第二个图片为需要设置的图片控件的id
    public void loadImg(final  String imgUrl , final int viewId){
        //建立一个线程
        Thread  thread  =  new Thread(){
            @Override
            public void run() {
                try{
                    //读取网络上的图片
                    Drawable    drawable    =   Drawable.createFromStream(new URL(imgUrl).
                            openStream() , "img.png");

                    //定义Message对象
                    Message  msg = ImageHandle.this.obtainMessage();
                    //设置Message对象的参数
                    msg.arg1  =  viewId ;
                    msg.obj   =  drawable ;
                    //调用handle的sendMessage函数
                    ImageHandle.this.sendMessage(msg);
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        };
        //启动线程
        thread.start();
        thread = null ;

    }
}
测试类:ThirdActivity:继承Activity,调用ImageHandle的loadImg方法,即可,代码如下:

package testsdcard.com.maiyu.s04_71.activity;

import android.app.Activity;
import android.os.Bundle;

import testsdcard.com.maiyu.s04_71.R;
import testsdcard.com.maiyu.s04_71.activity.handle.ImageHandle;

/**
 * Created by maiyu on 2016/7/16.
 */
public class ThirdActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third);

        //开启一个加载图片的handler,设置Iv1的图片
        ImageHandle  imageHandle1 = new ImageHandle(this);
        imageHandle1.loadImg("http://p0.so.qhimg.com/t01acc71e1e343e5f1a.jpg" ,R.id.Iv1);

        //开启一个加载图片的handler,设置Iv2的图片
        ImageHandle  imageHandle2 = new ImageHandle(this);
        imageHandle2.loadImg("http://www.it.com.cn/games/image/news/2009/12/03/16/jr1203ldd03.jpg", R.id.Iv2);

        //开启一个加载图片的handler,设置Iv3的图片
        ImageHandle  imageHandle3 = new ImageHandle(this);
        imageHandle3.loadImg("http://p2.so.qhimg.com/t0178e98dcb5581fa7c.jpg" , R.id.Iv3);
    }
}


添加网络权限:
 <uses-permission android:name="android.permission.INTERNET"></uses-permission>



结果:输出3个图片,可以滚动的,,,,图略



例子(2):从网络下载文件存到本地sdcard,可中断,同样利用handler + message

布局:activity_five:一个textView,一个editText,两个button(开始与结束),一个进度条

<?xml version="1.0" encoding="utf-8"?>
<!--定义基本布局:LinearLayout-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <!--一个TextView-->
    <TextView
        android:id="@+id/Tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/five_tv"/>
    <!--输入框-->
    <EditText
        android:id="@+id/Et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/five_et"/>
    <!--两个按钮:开始与停止-->
    <Button
        android:id="@+id/BtnStart"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/five_btn1"/>
    <Button
        android:id="@+id/BtnStop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/five_btn2"/>
    <!--进度条-->
    <ProgressBar
        android:id="@+id/Pb"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"/>

</LinearLayout>


strings的内容:

  <string name="button5">文件下载存入sdcard</string>
    <string name="five_tv">请输入下载地址</string>
    <string name="five_et">http://p1.so.qhimg.com/t0127d1282a580df751.jpg</string>
    <string name="five_btn1">开始下载</string>
    <string name="five_btn2">停止下载</string>



主类(都写在一起了):FiveActivity,实现handler和messge的操作,代码如下:

package testsdcard.com.maiyu.s04_79.activity;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import testsdcard.com.maiyu.s04_79.R;

/**
 * Created by maiyu on 2016/7/18.
 */
public class FiveActivity extends Activity {
    private ProgressBar pb ;        //定义进度条
    private TextView tv ;           //文本框和编辑框和两个按钮
    private EditText et ;
    private Button btnstart , btnstop ;
    private int fileSize , downLoadFileSize ;   //文件大小和已经下载的文件的大小
    private String filename ;       //文件名字
    private Thread thread ;         //线程对象

    //处理其他线程message的hanlder对象,根据message传来的数据去处理
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            //如果线程没有终止
            if(!Thread.currentThread().isInterrupted()){
                switch (msg.what){
                    //发送0--设置进度条总长,不用break继续判断
                    case 0 :
                        pb.setMax(fileSize);
                        //1--文件正在下载
                    case 1 :
                        pb.setProgress(downLoadFileSize);       //设置进度
                        int result = downLoadFileSize * 100 /fileSize ; //百分比
                        tv.setText(result + "%");
                        break;
                    case 2 :        //2---下载完毕
                        Toast.makeText(FiveActivity.this , "文件已下载完毕,请在sdcard下查看", Toast.LENGTH_SHORT).show();
                        break;
                    case 3 :        //下载被停止了
                        Toast.makeText(FiveActivity.this , "文件已停止下载" ,Toast.LENGTH_SHORT).show();
                        pb.setProgress(0);
                        tv.setText("0%");
                        break;
                    case -1 :       //-1---下载出错
                        String error = msg.getData().getString("error");
                        Toast.makeText(FiveActivity.this , error , Toast.LENGTH_SHORT).show();
                        break;
                }
            }

            super.handleMessage(msg);
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_five);
        findView();     //绑定id
        setListener();  //设置监听
    }

    //为两个按钮设置监听器
    private void setListener() {
        btnstart.setOnClickListener(mylistener);    //mylistener为自定义监听器
        btnstop.setOnClickListener(mylistener);
    }

    //自定义监听器
    View.OnClickListener  mylistener    =   new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            switch (view.getId()){
                case R.id.BtnStart :
                    //新开一个线程开始下载文件
                    thread  =   new Thread(){
                        @Override
                        public void run() {
                            try{
                                //得到下载地址
                                String str = et.getText().toString();
                                down_file(str , "/sdcard/");        //调用自定义方法down_file:存储在sdcard目录下
                                //down_file(str);
                            }catch (Exception e){
                                e.printStackTrace();
                            }
                            //super.run();
                        }
                    };
                    thread.start();     //启动线程
                    break;
                case R.id.BtnStop :
                    thread.interrupt();     //中断线程
                    break;
                default :
                    break;
            }
        }
    };

    //为各个控件绑定id
    private void findView() {
        pb  =   (ProgressBar)findViewById(R.id.Pb);
        tv  =   (TextView)findViewById(R.id.Tv);
        et  =   (EditText)findViewById(R.id.Et);
        btnstart    =   (Button)findViewById(R.id.BtnStart);
        btnstop     =   (Button)findViewById(R.id.BtnStop);
    }

    //根据url下载文件,保存在path下
    public void down_file(String url ,String path) throws IOException{
        filename    =   url.substring(url.lastIndexOf("/") + 1);    //得到文件名字
        URL  mURL   =   new URL(url);                       //创建URL
        URLConnection  conn  =  mURL.openConnection();      //得到URLConnection对象
        conn.connect();                                     //连接URLConnectioin
        InputStream  is  =  conn.getInputStream() ;         //得到输入流
        fileSize    =  conn.getContentLength() ;            //获取文件大小
        if(fileSize <= 0){
            throw new RuntimeException("文件无法获知大小");
        }
        if(is == null){
            throw new RuntimeException("数据流为空的");
        }

        //定义本地文件的读取流对象
        FileOutputStream  fos = new FileOutputStream(path + filename);
        //FileOutputStream  fos = new FileOutputStream(  Environment.getExternalStorageDirectory()+filename);

        byte buf[] = new byte[1024];        //byte[]数组,每次读取大小
        downLoadFileSize = 0 ;              //初始化
        sendMsg(0);                         //设置总的进度条
        do{
            int numread = is.read(buf);     //循环读取
            if(Thread.currentThread().isInterrupted()){
                sendMsg(3);     //中断时
                try{
                    is.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
                return;
            }
            if(numread == -1){      //完毕时退出循环
                break;
            }
            fos.write(buf , 0 , numread);       //写入
            downLoadFileSize += numread ;
            sendMsg(1);                 //更新进度
        }while (true);
        sendMsg(2);         //下载完毕
        try{
            is.close();         //关闭流
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //从子线程发送message给主线程
    private void sendMsg(int i) {
        Message message = new Message();
        message.what = i ;
        handler.sendMessage(message);
    }
}


记得添加权限:

分别是:访问网络权限;往sdcard写入权限;在sdcard下创建和删除权限

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



如何,去sdcard目录下,查看,发现刚刚下载的东西已经存在了


例子(3),足球明星图片和名字和简介网上加载:(C罗,梅西,纳尼)

布局:有两个

第一个:activity_second.xml放置一个listView,用于下拉,代码如下:

<?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">
    <!--定义列表布局ListView-->
    <ListView
        android:id="@+id/Lv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>
第二个:listview_second.xml:定义listView的每一个子项的内容格式,一个ImageView,两个TextView(名字和简介),代码:

<?xml version="1.0" encoding="utf-8"?>
<!--定义GridView的item的布局文件-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="40dp">
    <!--item的图片控件-->
    <ImageView
        android:id="@+id/ItemIv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"/>
    <!--item的姓名文字控件-->
    <TextView
        android:id="@+id/ItemTvName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@id/ItemIv"/>
    <!--item的简介文字控件-->
    <TextView
        android:id="@+id/ItemTvInfo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/ItemIv"/>

</RelativeLayout>
一个占位符类,类似于自定义适配器里的ViewHolder内部类(占位符):

ViewCache2---------- 主要定义刚刚布局的ImageView,2个TextView找到id

代码:

package testsdcard.com.maiyu.s04_79.domain;

import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import testsdcard.com.maiyu.s04_79.R;

/**定义视图的占位符类
 * Created by maiyu on 2016/7/17.
 */
public class ViewCache2 {
    private View baseView ;   //定义基本视图对象
    private TextView textViewname , textViewinfo ;  //定义要显示的标题,图片,信息
    private ImageView imageView ;

    //初始化基本视图
    public ViewCache2(View baseView){
        this.baseView = baseView ;
    }
    //3个get方法,分别得到图片,标题,信息
    public TextView getTextViewname(){
        if(textViewname == null){
            textViewname    =   (TextView)baseView.findViewById(R.id.ItemTvName);
        }
        return  textViewname ;
    }
    public TextView getTextViewinfo(){
        if(textViewinfo == null){
            textViewinfo    =   (TextView)baseView.findViewById(R.id.ItemTvInfo);
        }
        return  textViewinfo;
    }
    public ImageView getImageView(){
        if(imageView == null){
            imageView   =   (ImageView)baseView.findViewById(R.id.ItemIv);
        }
        return imageView ;
    }
}


一个异步图片加载类AsyncImageLoader2:

用HashMap<String , SoftReference<Drawable>> imageCache; 来存储缓存图片,再次加载此图片时,无需从网上加载,

其中String代表网址,判断该imageCache是否已经存有String这个网址了,有就用本地的缓存图片,无就网上加载

代码:if( imageCache.containsKey(imageUrl) ){//设置代码}

完整代码如下:

package testsdcard.com.maiyu.s04_79.domain;

import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;

import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;

/**定义异步加载图片类
 * Created by maiyu on 2016/7/17.
 */
public class AsyncImageLoader2 {
    //定义异步加载图片的缓存哈希图
    private HashMap<String ,SoftReference<Drawable>> imageCache ;
    public AsyncImageLoader2(){
        imageCache = new HashMap<String ,SoftReference<Drawable>>();
    }

    //获取图片的方法
    public Drawable loadDrawable(final  String imageUrl , final  ImageCallback imageCallback){

        //判断图片缓存中是否已经有此图片,有则返回
        if(imageCache.containsKey(imageUrl)){
            SoftReference<Drawable> softReference = imageCache.get(imageUrl);
            Drawable  drawable = softReference.get();
            if(drawable != null){
                return drawable ;
            }
        }

        //定义handler对象来发送message
        final Handler handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                imageCallback.imageLoaded((Drawable)msg.obj , imageUrl);
                //super.handleMessage(msg);
            }
        };

        //定义一个新的线程用来读取网络上的图片地址
        new Thread(){
            @Override
            public void run() {
                //读取图片地址imageUrl
                Drawable drawable = loadImageFromUrl(imageUrl);
                //将图片读取到的地址添加到缓存列表中
                imageCache.put(imageUrl , new SoftReference<Drawable>(drawable));
                //定义message对象,设置内容为加载到的图片对象
                Message message = handler.obtainMessage(0 , drawable);
                //发送图片
                handler.sendMessage(message);
              //  super.run();
            }
        }.start();
        return  null ;
    }

    //从图片地址读取图片
    public  static  Drawable loadImageFromUrl(String url){
        URL m ;
        InputStream i = null ;      //定义url对象,及inputstream对象
        try{
            //通过图片的url得到图片的inputStream对象
            m = new URL(url);
            i = (InputStream)m.getContent();
        }catch(Exception e){
            e.printStackTrace();
        }
        //通过inputStream对象得到图片的Drawable对象
        Drawable d  =   Drawable.createFromStream(i , "src");
        return d ;
    }

    //图片获取到后的接口
    public interface ImageCallback{
        public void imageLoaded(Drawable imageDrawable , String imageUrl);
    }
}


自定义适配器, ListViewAdapter:继承ArrayAdapter<ListItem>,重写getView()方法,在里面实现相关代码,占位符类已经在之前定了,故而不创建ViewHolder内部类了,代码如下:

package testsdcard.com.maiyu.s04_79.adapter;

import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import java.util.List;

import testsdcard.com.maiyu.s04_79.R;
import testsdcard.com.maiyu.s04_79.domain.AsyncImageLoader2;
import testsdcard.com.maiyu.s04_79.domain.ViewCache;
import testsdcard.com.maiyu.s04_79.domain.ViewCache2;
import testsdcard.com.maiyu.s04_79.moudle.ListItem;

/**
 * Created by maiyu on 2016/7/17.
 */
public class ListViewAdapter extends ArrayAdapter<ListItem> {
    private ListView listView ;
    //定义异步图片加载对象
    private AsyncImageLoader2 asyncImageLoader2 ;

    public ListViewAdapter(Context context , List<ListItem> imageAndTexts , ListView listView) {
        super(context, 0 , imageAndTexts);
        //初始化数据
        this.listView = listView ;
        asyncImageLoader2 = new AsyncImageLoader2();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Activity activity = (Activity)getContext() ;

        //读取GridView的item布局,读取griditem.xml布局
        View rowView = convertView ;
        ViewCache2 viewCache2 ;
        if(rowView == null){
            //读取griditem.xml为item的布局
            LayoutInflater inflater = activity.getLayoutInflater();
            rowView  = inflater.inflate(R.layout.listviewitem_second , null);
            //通过当前的布局视图,初始化缓存视图
            viewCache2 = new ViewCache2(rowView);
            //设置当前视图的标签
            rowView.setTag(viewCache2);
        }else{
            viewCache2 = (ViewCache2)rowView.getTag();
        }
        //得到需要显示的对象
        ListItem imageAndText = getItem(position);

        //读取对象的相应内容值
        String imageUrl = imageAndText.getImageUrl();
        ImageView imageView = viewCache2.getImageView() ;
        imageView.setTag(imageUrl);

        //读取缓存图片
        Drawable cachedImage = asyncImageLoader2.loadDrawable(imageUrl ,
              new   AsyncImageLoader2.ImageCallback(){

                  @Override
                  public void imageLoaded(Drawable imageDrawable, String imageUrl) {
                      //得到对应的ImageView对象
                      ImageView imageViewByTag = (ImageView)listView.findViewWithTag(imageUrl);
                      //设置图片控件显示的图像
                      if(imageViewByTag != null){
                          imageViewByTag.setImageDrawable(imageDrawable);
                      }
                  }
              });

        //如果缓存图片为空,显示默认图片
        if(cachedImage == null){
            imageView.setImageResource(R.drawable.ic_launcher);
        }else {
            imageView.setImageDrawable(cachedImage);
        }

        //显示姓名和简介
        TextView textViewname = viewCache2.getTextViewname();
        textViewname.setText(imageAndText.getName());
        TextView textViewinfo = viewCache2.getTextViewinfo();
        textViewinfo.setText(imageAndText.getInfo());
        return rowView;
    }
}


测试类:SecondActivity:继承Activity,绑定listView,添加自定义适配器(添加数据),为listView设置适配器(根据自定义适配器的构造函数,注意参数),代码如下:

package testsdcard.com.maiyu.s04_79.activity;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

import java.util.ArrayList;
import java.util.List;

import testsdcard.com.maiyu.s04_79.R;
import testsdcard.com.maiyu.s04_79.adapter.ListViewAdapter;
import testsdcard.com.maiyu.s04_79.moudle.ListItem;

/**
 * Created by maiyu on 2016/7/17.
 */
public class SecondActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        ListView listView = (ListView)findViewById(R.id.Lv);
        //定义数据list
        List<ListItem> list = new ArrayList<ListItem>();
        //添加数据
        list.add(new ListItem("http://p1.so.qhimg.com/t011e24c3af6772acf6.jpg" ,"C罗" ,"克里斯蒂亚诺·罗纳尔多(Cristiano Ronaldo),1985年2月5日出生于葡萄牙马德拉岛丰沙尔。简称C罗,葡萄牙足球运动员,司职边锋可兼任中锋,现效力于西甲皇家马德里足球俱乐部,并身兼葡萄牙国家队队长。"));
        list.add(new ListItem("http://p1.so.qhimg.com/t019d0526e85eaa9ab6.jpg" ,"梅西","莱昂内尔·安德列斯·梅西(西班牙语:Lionel Andrés Messi),1987年6月24日生于阿根廷圣菲省罗萨里奥,绰号“新马拉多纳”,阿根廷著名足球运动员,司职前锋、边锋和前腰,现效力于西班牙足球甲级联赛巴塞罗那足球俱乐部。"));
        list.add(new ListItem("http://www.188score.com/Upload/2_img2013_10/730_932348_927160.jpg","纳尼","路易斯·卡洛斯·阿尔梅达·达·库尼亚(Luis Carlos Almeida da Cunha),男,也叫\"纳尼\",葡萄牙著名足球运动员,现效力于土耳其的费内巴切足球俱乐部,曾效力于曼彻斯特联足球俱乐部、里斯本竞技足球俱乐部。"));
        list.add(new ListItem("http://p1.so.qhimg.com/t011e24c3af6772acf6.jpg" ,"C罗" ,"克里斯蒂亚诺·罗纳尔多(Cristiano Ronaldo),1985年2月5日出生于葡萄牙马德拉岛丰沙尔。简称C罗,葡萄牙足球运动员,司职边锋可兼任中锋,现效力于西甲皇家马德里足球俱乐部,并身兼葡萄牙国家队队长。"));
        list.add(new ListItem("http://p1.so.qhimg.com/t019d0526e85eaa9ab6.jpg" ,"梅西","莱昂内尔·安德列斯·梅西(西班牙语:Lionel Andrés Messi),1987年6月24日生于阿根廷圣菲省罗萨里奥,绰号“新马拉多纳”,阿根廷著名足球运动员,司职前锋、边锋和前腰,现效力于西班牙足球甲级联赛巴塞罗那足球俱乐部。"));
        list.add(new ListItem("http://www.188score.com/Upload/2_img2013_10/730_932348_927160.jpg","纳尼","路易斯·卡洛斯·阿尔梅达·达·库尼亚(Luis Carlos Almeida da Cunha),男,也叫\"纳尼\",葡萄牙著名足球运动员,现效力于土耳其的费内巴切足球俱乐部,曾效力于曼彻斯特联足球俱乐部、里斯本竞技足球俱乐部。"));
        list.add(new ListItem("http://p1.so.qhimg.com/t011e24c3af6772acf6.jpg" ,"C罗" ,"克里斯蒂亚诺·罗纳尔多(Cristiano Ronaldo),1985年2月5日出生于葡萄牙马德拉岛丰沙尔。简称C罗,葡萄牙足球运动员,司职边锋可兼任中锋,现效力于西甲皇家马德里足球俱乐部,并身兼葡萄牙国家队队长。"));
        list.add(new ListItem("http://p1.so.qhimg.com/t019d0526e85eaa9ab6.jpg" ,"梅西","莱昂内尔·安德列斯·梅西(西班牙语:Lionel Andrés Messi),1987年6月24日生于阿根廷圣菲省罗萨里奥,绰号“新马拉多纳”,阿根廷著名足球运动员,司职前锋、边锋和前腰,现效力于西班牙足球甲级联赛巴塞罗那足球俱乐部。"));
        list.add(new ListItem("http://www.188score.com/Upload/2_img2013_10/730_932348_927160.jpg","纳尼","路易斯·卡洛斯·阿尔梅达·达·库尼亚(Luis Carlos Almeida da Cunha),男,也叫\"纳尼\",葡萄牙著名足球运动员,现效力于土耳其的费内巴切足球俱乐部,曾效力于曼彻斯特联足球俱乐部、里斯本竞技足球俱乐部。"));
        list.add(new ListItem("http://p1.so.qhimg.com/t011e24c3af6772acf6.jpg" ,"C罗" ,"克里斯蒂亚诺·罗纳尔多(Cristiano Ronaldo),1985年2月5日出生于葡萄牙马德拉岛丰沙尔。简称C罗,葡萄牙足球运动员,司职边锋可兼任中锋,现效力于西甲皇家马德里足球俱乐部,并身兼葡萄牙国家队队长。"));
        list.add(new ListItem("http://p1.so.qhimg.com/t019d0526e85eaa9ab6.jpg" ,"梅西","莱昂内尔·安德列斯·梅西(西班牙语:Lionel Andrés Messi),1987年6月24日生于阿根廷圣菲省罗萨里奥,绰号“新马拉多纳”,阿根廷著名足球运动员,司职前锋、边锋和前腰,现效力于西班牙足球甲级联赛巴塞罗那足球俱乐部。"));
        list.add(new ListItem("http://www.188score.com/Upload/2_img2013_10/730_932348_927160.jpg","纳尼","路易斯·卡洛斯·阿尔梅达·达·库尼亚(Luis Carlos Almeida da Cunha),男,也叫\"纳尼\",葡萄牙著名足球运动员,现效力于土耳其的费内巴切足球俱乐部,曾效力于曼彻斯特联足球俱乐部、里斯本竞技足球俱乐部。"));

        listView.setAdapter(new ListViewAdapter(this , list , listView));
    }
}


记得添加网络权限:

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

结果:

出现一张可以下拉的帅气的C罗,梅西,纳尼的简介表,,,略

四,当然Looper与handler和message,messageQueue渊源很大,且经常在一起,,,待续,,,


  • 1
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页
评论

打赏作者

Android开始之路

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值