魔乐科技安卓开发教程----李兴华----04消息机制(Message、Looper、Handler)

1.Message消息传送

Message主要功能是对消息(字符串,对象?)进行封装,并同时指定消息的操作形式

在这里插入图片描述
以下代码不推荐,子线程不能改变主线程ui

public class MainActivity extends AppCompatActivity {
    private TextView info;
    private static  int count=0;//更新后的记录
    private static final int SET=1; //操作的状态

    private Handler myHandler=new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){//what是一个数字的消息内容
                case SET:
                   info.setText("fengray-"+(count++));
                   break;
            }
        }
    };

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

        info=findViewById(R.id.info);
        Timer timer=new Timer();
        timer.schedule(new MyTask(),0,1000);

    }
    //定时调度类
    public class MyTask extends TimerTask{

        @Override
        public void run() {
            Message msg=new Message();//设置更新
            msg.what=SET;
            MainActivity.this.myHandler.sendMessage(msg);//发送消息

        }
    }
}

结果
在这里插入图片描述

2.Looper通道

方法一:此方法不用looper一样能够实现
因为不适用looper,也会自动创建一个looper

public class MainActivity extends AppCompatActivity {
    private TextView info;
    private Button mybut;
    private static  int count=0;//更新后的记录
    private static final int SET=1; //操作的状态

    private MyHandler myHandler=null;

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

        info=findViewById(R.id.info);
        mybut=findViewById(R.id.mybut);

        mybut.setOnClickListener(new OnClickListenerImp());

    }

    private class OnClickListenerImp implements View.OnClickListener{

        @Override
        public void onClick(View v) {
            Looper looper=Looper.myLooper();//mylooper是内置的静态方法
            myHandler=new MyHandler(looper);
            myHandler.removeMessages(0);//清空所有的消息
            String data="中国四大名著笑傲江湖";
            Message msg=myHandler.obtainMessage(SET,1,1,data);//创建消息
            myHandler.sendMessage(msg);
        }
    }

    private class MyHandler extends  Handler{

        public MyHandler(Looper looper){
            super(looper);
        }

        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){//what是一个数字的消息内容
                case SET:
                    MainActivity.this.info.setText(msg.obj.toString());
                    break;
            }
        }
    }

}

结果:
在这里插入图片描述

3.主线程和子线程之间数据交换

子线程作为耗时线程
本例中子线程在后台输出,主线程可以更新ui
在这里插入图片描述

public class MainActivity extends AppCompatActivity {
    public static  final int SETMAIN=1;//设置一个what标记
    public static  final int SETCHILD=2;//设置一个what标记
    private Handler mainHandler,childHandler;
    private TextView msg;
    private Button mybut;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        msg=findViewById(R.id.msg);
        mybut=findViewById(R.id.mybut);
        mainHandler=new Handler(){
            @Override
            public void handleMessage(@NonNull Message mymsg) {//接收从子线程返回来的数据
                switch (mymsg.what){
                    case SETMAIN:
                        msg.setText("主线程接收数据:"+mymsg.toString());
                }
            }
        };
        new Thread(new ChildThread(),"子线程").start();
        mybut.setOnClickListener(new OnclickListenerImpl());
    }

    private class OnclickListenerImpl implements View.OnClickListener{

        @Override
        public void onClick(View v) {//将信息发送到子线程之中
            if (childHandler!=null){
                Message childMsg=childHandler.obtainMessage();//创建消息
                childMsg.obj=mainHandler.getLooper().getThread().getName()+"hello android";
                childMsg.what=SETCHILD;
                childHandler.sendMessage(childMsg);
            }
        }
    }

    class ChildThread implements Runnable{

        @Override
        public void run() {//子线程
            Looper.prepare();//准备好looper对象
            childHandler=new Handler(){
                @Override
                public void handleMessage(@NonNull Message msg) {
                    switch (msg.what){
                        case SETCHILD://子线程接受主线程发来的消息
                            Log.d("jian", "main child message: "+msg.obj);//输出数据
                            Message toMain=mainHandler.obtainMessage();
                            toMain.obj="\n\n***这是子线程发送给主线程的信息***"+super.getLooper().getThread().getName();
                            toMain.what=SETMAIN;
                            mainHandler.sendMessage(toMain);
                            break;
                    }
                }
            };
            Looper.loop();//创建消息队列
        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        childHandler.getLooper().quit();
    }
}

结果是:
在这里插入图片描述

3.Message消息传送时钟案例
public class MainActivity extends AppCompatActivity {
    private AnalogClock clock=null;
    private TextView info=null;
    private static final int SET=1;
    private Handler handler=new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case SET://一旦信息的格式(钩子)what,符合条件者处理信息
                    info.setText("当前时间为:"+msg.obj.toString());
                    break;
            }
        }
    };

    //创建子线程
    private class ClockThread implements Runnable{

        @Override
        public void run() {
            while(true){//一直更新
                //用格式化时间来获取信息,实际是就是包装了一个信息进去
                Message mymsg=handler.obtainMessage(SET,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
                //将包装好的信息发送出去
                handler.sendMessage(mymsg);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }


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

        info=findViewById(R.id.mytext);
        //启动子线程,子线程想主线程返回数据
        new Thread(new ClockThread()).start();
    }
}

结果是:
在这里插入图片描述

4.进度条组件ProgressBar(利Message消息来更新主线程UI)

当子线程无法更新主线程ui时,则应当由子线程向主线程发送消息,来更新ui

public class MainActivity extends AppCompatActivity {
    private static final int STOP=1;
    private static final int CONTINUE=2;
    private ProgressBar progressbarA,progressbarB;
    private Button mybut=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        progressbarA=findViewById(R.id.myproA);
        progressbarB=findViewById(R.id.myproB);
        mybut=findViewById(R.id.mybut);
        progressbarB.setIndeterminate(false);//设置进度条为不确定模式
        mybut.setOnClickListener(new OnclickListenerImpl());

    }

    private class OnclickListenerImpl implements View.OnClickListener{

        @Override
        public void onClick(View v) {
            progressbarA.setVisibility(View.VISIBLE);
            progressbarB.setVisibility(View.VISIBLE);
            progressbarA.setMax(100);
            progressbarB.setMax(100);
            progressbarA.setProgress(0);
            progressbarB.setProgress(0);

            new Thread(new Runnable(){//创建一个匿名线程来处理子线程
                @Override
                public void run() {
                    int count=0;
                    for (int i = 0; i <100 ; i++) {
                        count=i;
                        try {
                            Thread.sleep(50);//延迟500毫秒
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        if (i==99){
                            Message mymsg=new Message();
                            mymsg.what=STOP;//主程序activity的停止状态(变量)
                            myMessageHandler.sendMessage(mymsg);
                        }else {
                            Message mymsg=new Message();
                            mymsg.what=CONTINUE;//主程序activity的继续状态(变量)
                            mymsg.arg1=count;
                            myMessageHandler.sendMessage(mymsg);
                        }
                    }


                }
            }).start();

        }
    }

    private Handler myMessageHandler=new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case STOP:
                    progressbarB.setVisibility(View.GONE);//当子线程的发来的消息的what为STOP则,设置其为不可见
                    Thread.currentThread().interrupt();//中断当前线程
                    break;
                case CONTINUE:
                    if (!Thread.currentThread().isInterrupted()){
                        progressbarB.setProgress(msg.arg1);//拿到子线程的消息中的count值,再将其设置在主线程的progressbarB组件上
                    }
                    break;
            }
        }
    };
}

结果
状态1:正在增长的状态
在这里插入图片描述
状态2:增长到完成后隐藏进度条
在这里插入图片描述

5.异步处理工具类:AsyncTask
public class MainActivity extends AppCompatActivity {
    private ProgressBar mypro=null;
    private TextView show=null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mypro=findViewById(R.id.mypro);
        show=findViewById(R.id.show);

        ChildUpdate childUpdate=new ChildUpdate();
        childUpdate.execute(100);
    }

    //子线程更新,每次处理后台进度的类型是Integer、更新之后的数值是Integer,最后的结果返回的是字符串
    private class ChildUpdate extends AsyncTask<Integer,Integer,String>{
        @Override
        protected void onPostExecute(String resualt) {//更新结果值
            show.setText(resualt);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {//每次更新之后的内容
            show.setText("当前的进度值为:"+String.valueOf(values[0]));
        }

        @Override
        //每次的进度处理,可以更新UI组件
        protected String doInBackground(Integer... integers) {
            for (int i = 0; i <100 ; i++) {
                mypro.setProgress(i);//设置进度
                publishProgress(i);//更新,调用更新操作
                try {
                    Thread.sleep(integers[0]);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return "执行完毕";
        }
    }
}

结果为
在这里插入图片描述
在这里插入图片描述

6.使用AsyncTask异步创建一个简易的文件管理系统(未能实现,找不到错误在哪)

1、给simpleAdapter设置一个布局文件mylayout.xml

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TableRow>
        <ImageView android:id="@+id/img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </TableRow>
</TableLayout>

2、activity文件

public class MainActivity extends AppCompatActivity {
    private ListView list=null;
    private List<Map<String ,Object>> allFileItems=new ArrayList<>();
    private SimpleAdapter simpleAdapter=null;
    private ListFileThread fileThread=null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        list=findViewById(R.id.mylist);
        File filePath=new File(File.separator);//从根目录下开始列出

        //线程操作
        fileThread=new ListFileThread();//自定义线程类
        fileThread.execute(filePath);
        list.setOnItemClickListener(new OnItemClickListenerImpl());


    }

    private class OnItemClickListenerImpl implements AdapterView.OnItemClickListener{

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            File currenFile= (File) allFileItems.get(position).get("name");
            if (currenFile.isDirectory()){//当前是一个目录
                allFileItems=new ArrayList<Map<String, Object>>();
                fileThread=new ListFileThread();
                fileThread.execute(currenFile);
            }
        }
    }

    private class ListFileThread extends AsyncTask<File,File,String>{
        //进度处理操作
        @Override
        protected void onProgressUpdate(File... values) {
            Log.d("jian", "onProgressUpdate: ");
            Map<String,Object> fileItem=new HashMap<String, Object>();//表示可以返回?
            if (values[0].isDirectory()){//是文件夹
                fileItem.put("img",R.drawable.fileclose);
            }else{
                fileItem.put("img",R.drawable.file);
            }
            fileItem.put("name",values[0]);
            allFileItems.add(fileItem);
            simpleAdapter=new SimpleAdapter(MainActivity.this,allFileItems,R.layout.mylayout,
                    new String[]{"img","name"},new int[] {R.id.img,R.id.name});
            list.setAdapter(simpleAdapter);
        }

        //每次进行列表操作及更新
        @Override
        protected String doInBackground(File... files) {
            Log.d("jian", "doInBackground:1111111111 ");
            if (!files[0].getPath().equals(File.separator)){//如果不是根目录
                Map<String,Object> fileItem=new HashMap<String, Object>();//表示可以返回?
                fileItem.put("img",R.drawable.fileopen);
                fileItem.put("name",files[0].getParentFile());
                allFileItems.add(fileItem);
            }
            Log.d("jian", "doInBackground:222222 ");

            if (files[0].isDirectory()){
                File tempFiles[] =files[0].listFiles();
                if (tempFiles!=null){
                    for (int i = 0; i <tempFiles.length ; i++) {
                        this.publishProgress(tempFiles[i]);
                    }
                }
            }
            return "文件已列出";
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值