1.线程的启动方式:
第一种方式:
class MyThread extends Thread{
public void run(){
// 写耗时操作代码
// Only the original thread that created a view hierarchy can touch its views.
// 如果子线程已经执行了耗时操作,那么就不能修改视图的属性了;视图的属性只能在UI线程去修改
}
}
MyThread myThead = new MyThread();
myThread.start();
第二种方式:
class MyRunnable implements Runnable {
@Override
public void run() {
try {
Thread.sleep(3000);
String result = "runnable 345345";
Log.i("runnable", result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
第三种方式(最常使用的):
new Thread(new Runnable() {
@Override
public void run() {
// 耗时任务
try {
Thread.sleep(3000);
String result = "匿名线程";
Log.i("匿名线程",result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
2.Handler
2.1Handler使用
/**
* 从服务器接收到用户的昵称,并将昵称设置在textview对应的text属性上
*
* 连接服务器的功能,是属于耗时任务,所以必须放在子线程
*
* 子线程中是没有办法修改页面,借助Handler给主线程传递消息
*
* 主线程接收到消息后,开始执行修改UI
2.2实例
public class MainActivity2 extends AppCompatActivity {
// 声明容器
private TextView tv1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
// 根据ID获取页面控件
tv1 = findViewById(R.id.tv1);
// 模拟一个连接服务器的过程
new Thread(new Runnable() {
@Override
public void run() {
try {
// 本意是想表达 连接服务器的耗时操作
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 假如从服务器获取到昵称为:炸炸最炸
String result = "炸炸最炸";
// 将昵称给textview设置上,在子线程中更新UI,是不允许的,必须使用handler将消息传递回去
Message message = new Message();
message.what = 1;
message.obj = result;
handler.sendMessage(message);
}
}).start();
}
private Handler handler = new Handler(Looper.getMainLooper()){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what == 1) {
String result = (String) msg.obj;
tv1.setText(result);
}
}
};
}
3.进度条
通过使用Handler来完成进度条加载
public class MainActivity3 extends AppCompatActivity {
private ProgressBar progressBar;
int status = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
progressBar = findViewById(R.id.progressBar);
new Thread(new Runnable() {
@Override
public void run() {
// 循环对status进行值得修改
while (status < 100) {
try {
Thread.sleep(100);
status++;
handler.sendEmptyMessage(0x111);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
private Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if (msg.what == 0x111) {
progressBar.setProgress(status);
}
}
};
}
4.Server解决ANR
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("serivce","服务已开启");
new Thread(new Runnable() {
@Override
public void run() {
long endtime = System.currentTimeMillis() + 20 * 1000; // 获取当前系统再加上20秒
while(System.currentTimeMillis() < endtime) {
synchronized (this){
try {
wait(endtime - System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
stopSelf();
}
}).start();
return super.onStartCommand(intent, flags, startId);
}
结论:
Service不会自动开启线程,也不会自动停止线程
5.IntentService
如何创建一个IntentService
new Class-> MyIntentService ->继承IntentService->实现onHandleIntent 和 构造方法
在AndroidManifest.xml中注册,注册时发现报错,报错的原因是没有无参的构造方法,解决办法:创建无参的构造方法
Activity 耗时操作 子线程, handler
Service
IntentService 自动开启线程,并在执行完毕后,关闭线程
代码如下:
package com.hopu.intentdemo;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;
import androidx.annotation.Nullable;
import java.io.File;
public class MyIntentService extends IntentService {
public MyIntentService(){
super("MyIntentService");
}
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public MyIntentService(String name) {
super(name);
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
Log.i("IntentService","IntentService已开始");
long endtime = System.currentTimeMillis() + 20 * 1000;
while(System.currentTimeMillis() < endtime) {
synchronized (this){
try {
wait(endtime-System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@Override
public void onDestroy() {
Log.i("IntentService","IntentService已销毁");
super.onDestroy();
}
}
6.HandlerThread
话不多说,直接上代码
package com.hopu.intentdemo;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity3 extends AppCompatActivity {
private TextView tv_show2;
// HandlerThread
private HandlerThread mHandlerThread;
// 子线程的句柄
private Handler threadHandler;
// 主线程的句柄
private Handler mHanler = new Handler();
private String result = "hopu";
private boolean isRun;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
tv_show2 = findViewById(R.id.tv_show2);
mHandlerThread = new HandlerThread("check_message");
mHandlerThread.start();
threadHandler = new Handler(mHandlerThread.getLooper()){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
try {
Thread.sleep(2000);
result = result + 1;
if (isRun)
threadHandler.sendEmptyMessage(0x111);
} catch (InterruptedException e) {
e.printStackTrace();
}
mHanler.post(new Runnable() {
@Override
public void run() {
tv_show2.setText(result);
}
});
}
};
}
@Override
protected void onResume() {
super.onResume();
isRun = true;
threadHandler.sendEmptyMessage(0x111);
}
@Override
protected void onPause() {
super.onPause();
isRun = false;
threadHandler.sendEmptyMessage(0x111);
}
@Override
protected void onDestroy() {
super.onDestroy();
mHandlerThread.quit();
}
}
本文含有隐藏内容,请 开通VIP 后查看