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 "文件已列出";
}
}
}