1、定义一个线程只需要新建一个类继承自Thread。然后重写run()方法,并在里面编写耗时逻辑即可:
class MyThread extends Thread{ public void run(){ //处理具体的逻辑 } }
启动的时候只需要new出MyThread的实例,然后调用它的start()方法,这样run()中写的代码就会在子线程中进行:
new Mythread().start();
2、更多时候使用实现Runnable接口的方式来定义一个线程
class MyThread implements Runnable { public void run() { //处理具体的逻辑 } }
如果使用了这种写法,启动线程的方法也要进行相应的改变:
MyThread mythread = new MyThread(); new Thread(mythread).start();
Thread的构造函数接收了一个Runnable参数,MyThread正是一个实现了Runnable接口的对象,所以直接将它传入Thread的构造函数里,紧接着调用start()方法,run()中的代码就会在子线程中运行了。
3、如果不想专门再定义一个类去实现Runnable接口,也可以使用匿名类的方式:
new Thread (new Runnable() { public void run() { //处理具体的逻辑 } }).start();
例如:在子线程中更新UI,
android的UI是线程不安全的,也就是说如果想要更新应用程序里的UI元素,就必须要在主线程中进行,否则就会出现意外。
验证一下就是:先在布局中加入一个按钮和一个文本控件,
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="match_parent" 3 android:layout_height="match_parent"> 4 5 6 <Button 7 android:id="@+id/chage_text" 8 android:layout_width="match_parent" 9 android:layout_height="wrap_content" 10 android:text="改变文字" /> 11 12 <TextView 13 android:id="@+id/textView" 14 android:layout_width="wrap_content" 15 android:layout_height="wrap_content" 16 android:layout_centerInParent="true" 17 android:text="这是一段文字" 18 android:textSize="20sp"/> 19 </RelativeLayout>
然后是java代码:
1 public class MainActivity extends AppCompatActivity { 2 @Override 3 protected void onCreate(Bundle savedInstanceState) { 4 super.onCreate(savedInstanceState); 5 setContentView(R.layout.activity_main); 6 7 //注册按钮和文本控件 8 Button changeText = (Button) findViewById(R.id.chage_text); 9 final TextView textView = (TextView) findViewById(R.id.textView); 10 11 //按钮响应 12 changeText.setOnClickListener(new View.OnClickListener() { 13 @Override 14 public void onClick(View view) { 15 16 //开启一个子线程 17 new Thread(new Runnable() { 18 @Override 19 public void run() { 20 21 //修改文本控件中的文本 22 textView.setText("这是另一段文字"); 23 } 24 }).start(); 25 } 26 }); 27 } 28 }
然后安装到手机上,然后就崩溃了,前面就说过要改变UI就需要在主线程中去改变。这时候就需要使用一套异步消息处理机制,也就是子线程中发送消息给Handler,然后Handler识别消息再去进行相应的操作。
1 public class MainActivity extends AppCompatActivity { 2 3 public static final int UPDATA_TEXT = 1; 4 5 private TextView textView; 6 7 private Handler handler = new Handler(){ 8 9 public void handleMessage(Message msg){ 10 switch (msg.what){ 11 case UPDATA_TEXT: 12 textView.setText("这是另一段文字"); 13 break; 14 default: 15 break; 16 } 17 } 18 }; 19 @Override 20 protected void onCreate(Bundle savedInstanceState) { 21 super.onCreate(savedInstanceState); 22 setContentView(R.layout.activity_main); 23 24 //注册按钮和文本控件 25 Button changeText = (Button) findViewById(R.id.chage_text); 26 textView = (TextView) findViewById(R.id.textView); 27 28 //按钮响应 29 changeText.setOnClickListener(new View.OnClickListener() { 30 @Override 31 public void onClick(View view) { 32 33 //开启一个子线程 34 new Thread(new Runnable() { 35 @Override 36 public void run() { 37 Message message = new Message(); 38 message.what = UPDATA_TEXT; 39 handler.sendMessage(message);//将Message对象发送出去 40 } 41 }).start(); 42 } 43 }); 44 } 45 }
先创建一个Handler对象,并重写handleMessage方法用于对具体Message的处理,在这里对UI进行改变,然后在子线程中创建一个Message对象,将Message的what字段指定为提取设置好的值,然后调用handler的sendMessage()方法发送出去。