android中的多线程是指同时执行多个线程任务,这些线程可以独立运行,互不干扰,可以提高程序的运行效率,使程序具有更好的响应能力。下面我们将介绍android多线程的基本概念、使用方法及案例说明。
一、基本概念
1.线程:线程是程序中执行任务的最小单元,它是程序中的独立执行流。每个线程都有独立的处理器时间片和堆栈空间,线程之间可以共享程序中的数据和资源。
2.并发和并行:并发和并行都是指同时执行多个任务的方式。并行指同时执行多个任务,每个任务在不同的处理器上运行,而并发则是指同时执行多个任务,这些任务在同一个处理器上轮流执行。
3.主线程:android应用程序启动时会自动创建一个主线程,也叫ui线程,在这个线程中处理用户界面的显示和io操作。主线程是android应用程序的核心,很多重要的操作都必须在主线程中进行。
4.子线程:在android中,可以创建多个子线程,这些线程都是在主线程之外运行的。子线程可以执行比较耗时的操作,如网络请求,文件读写等,从而保证主线程的响应速度。
二、使用方法
1.继承thread类创建线程
使用继承thread类的方式创建线程,需要重写thread类的run()方法,该方法中定义了线程所要执行的任务,代码如下:
```
public class mythread extends thread {
@override
public void run() {
super.run();
//线程执行的代码
log.e(tag,"当前线程名称:" thread.currentthread().getname());
}
}
```
在代码中,我们通过继承thread类并重写run()方法来创建一个新的线程。在run()方法中定义线程所要执行的任务,线程中的代码会在run()方法中被执行。
创建线程后,可以通过调用start()方法来启动线程,并开始执行run()方法中定义的任务。
```
mythread mythread = new mythread();
mythread.start();
```
2.实现runnable接口创建线程
中支持通过实现runnable接口的方式创建线程,这种方式更加灵活,推荐使用。实现runnable接口的方式创建线程,需要实现runnable接口中的run()方法,该方法中定义了线程所要执行的任务,代码如下:
```
public class myrunnable implements runnable {
@override
public void run() {
//线程执行的代码
log.e(tag,"当前线程名称:" thread.currentthread().getname());
}
}
```
在代码中,我们通过实现runnable接口并重写run()方法来创建一个新的线程。在run()方法中定义线程所要执行的任务,线程中的代码会在run()方法中被执行。
创建线程后,可以通过thread类的构造函数来初始化线程,并将runnable对象作为参数传递给线程,然后通过调用线程的start()方法来启动线程。
```
myrunnable myrunnable = new myrunnable();
thread thread = new thread(myrunnable);
thread.start();
```
3.使用匿名内部类创建线程
android中支持使用匿名内部类的方式创建线程,它可以让代码更加简洁。通过匿名内部类的方式创建线程,可以省略创建一个新的类,代码如下:
```
thread thread = new thread(new runnable() {
@override
public void run() {
//线程执行的代码
log.e(tag,"当前线程名称:" thread.currentthread().getname());
}
});
thread.start();
```
通过匿名内部类的方式,可以继承runnable接口,并重写其中的run()方法,后面的代码表示直接调用thread的构造方法,创建一个新的线程,并启动该线程。
三、案例说明
下面我们通过一个案例来说明android中多线程的使用方法。
案例:使用thread类创建两个线程,分别进行网络请求和文件读写操作,并将结果显示到ui线程中。
1.布局文件
我们首先需要创建一个布局文件,其中包含一个textview,用来显示网址及读取文件的结果。
```
android:layout_height="match_parent">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textsize="20sp"/>
```
2.创建线程
我们通过继承thread类的方式创建两个线程,分别进行网络请求和文件读写操作。网络请求的线程用于从指定网址读取数据,文件读写的线程用于从sd卡中读取文件内容。
```
public class networkthread extends thread {
private string murl;
private handler mhandler;
public networkthread(string url, handler handler) {
murl = url;
mhandler = handler;
}
@override
public void run() {
super.run();
string result = httputils.doget(murl);//执行网络请求,并返回结果
message message = new message();
message.what = 1;//用于标识消息的类型
message.obj = result;//将结果保存到消息对象中
mhandler.sendmessage(message);//发送消息到主线程中
}
}
public class filethread extends thread {
private string mfilepath;
private handler mhandler;
public filethread(string filepath, handler handler) {
mfilepath = filepath;
mhandler = handler;
}
@override
public void run() {
super.run();
string result = fileutils.readfile(mfilepath);//读取文件,并返回结果
message message = new message();
message.what = 2;//用于标识消息的类型
message.obj = result;//将结果保存到消息对象中
mhandler.sendmessage(message);//发送消息到主线程中
}
}
```
在代码中,我们分别创建了两个线程,networkthread用于进行网络请求操作,filethread用于进行文件读写操作。这两个线程都需要一个handler对象作为参数,用于发送消息到主线程中。
3.主线程
我们在mainactivity中定义了一个handler对象,用于在主线程中接收来自子线程的消息,并显示结果。
```
public class mainactivity extends appcompatactivity {
private textview mtvresult;
private handler mhandler = new handler() {
@override
public void handlemessage(message msg) {
super.handlemessage(msg);
if (msg.what == 1) {//来自网络请求线程的消息
string result = (string) msg.obj;
mtvresult.settext("网址:" murl "\n网络请求结果:" result);
} else if (msg.what == 2) {//来自文件读写线程的消息
string result = (string) msg.obj;
mtvresult.settext("文件路径:" mfilepath "\n文件读写结果:" result);
}
}
};
private string murl = "https://www.baidu.com/";
private string mfilepath = environment.getexternalstoragedirectory().getabsolutepath() "/test.txt";
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
mtvresult = findviewbyid(r.id.tv_result);
}
public void networkbuttonclick(view view) {
networkthread networkthread = new networkthread(murl, mhandler);
networkthread.start();
}
public void filebuttonclick(view view) {
filethread filethread = new filethread(mfilepath, mhandler);
filethread.start();
}
}
```
在主线程中,我们定义了一个handler对象,重写了handlemessage()方法,用于在接收来自子线程的消息后显示结果。我们在oncreate()方法中获取布局文件中的textview,通过两个按钮分别启动networkthread线程和filethread线程,并将handler对象作为参数传递给两个线程。
四、总结
使用多线程可以大大提高android应用程序的运行效率和响应能力。在开发过程中,需要注意以下几点:
1.主线程不能阻塞:在执行一些比较费时的操作时,需要使用子线程来完成,避免主线程被阻塞。
2.多线程需要互斥:多个线程同时访问共享数据时,容易出现数据异常,需要使用锁或其他同步机制来确保数据的正确性。
3.ui操作需要在主线程中进行:ui界面的操作必须在主线程中进行,否则会出现异常或其他问题。
综上所述,android中的多线程使用非常重要,掌握了多线程的开发技巧和注意事项,可以让我们更加高效地开发android应用程序。 凯时尊龙app-尊龙凯时国际娱乐 是是一个二次元爱好者交换资源的平台,提供最及时,最全面的galgame、漫画、单机游戏、同人游戏的宝贵资源。
链接失效的请留言 ,我看见了就补上!!!
1.网站内容来源于互联网,我们将这些信息转载出来的初衷在于分享与学习,这并不意味着我们站点对这些信息的观点或真实性作出认可,我们也不承担对这些信息的责任。
2.若出现任何侵权或其他问题,敬请通过电子邮件与管理员联系,我们将尽快采取行动予以删除。
发表评论