Android多线程编程(一)——多线程基础

什么是进程

  一个进程是一个独立(self contained)的运行环境,它可以看作一个程序或者一个应用。

什么是线程

  而线程是进程中执行的一个任务,Java运行环境是一个包含了不同累和程序的单一进程。线程可以被称为轻量级进程。线程需要较少的资源来创建和驻留在进程中,并且可以共享进程中的资源。

Android线程

  Android的线程,实际上和Java的多线程编程并没有什么本质上的不同。当我们需要执行一些耗时操作,比如说发起一条网络请求时,考虑到网速等其他原因,服务器未必会立刻响应我们的请求,如果不将这类操作放在子线程中运行,就会导致主线程被阻塞住,从而影响用户对软件的正常使用。

线程的基本用法

  Android多线程编程其实并不比Java多线程特殊,基本都是使用相同的语法。有两种创建线程的方法:

  一是新建一个继承自Thread的类,然后重写父类的run()方法,并在里面编辑耗时逻辑即可,如:

1 public class MyThread extends Thread{
2     @Override
3     public void run(){
4                 //具体处理的逻辑
5     }
6 }

  启动这个线程的方法也很简单,只需要new出MyThread的实例,然后调用它的start方法,这样run()方法中的代码就会在子线程中运行,如

new MyThread().start();

  然而,使用继承的耦合性比较高,更多的时候使用实现Runnable接口是一个不错的选择,如:

1 public class MyThread implements Runnable{
2     @Override
3     public void run(){
4                 //具体处理的逻辑
5     }
6 }

  如果使用了这种写法,启动线程的方法也需要进行相应的改变,如:

MyThread myThread = new MyThread();
new Thread(myThread).start();

  可以看到,Thread的构造函数接收一个Runnable参数,而new出的MyThread正是一个实现了Runnable接口的对象,所以可以将它直接传入到Thread的构造函数里。接着调用Thread的start()方法,run()方法中的代码就会在子线程中运行。

Android中的多线程

  和许多其他的GUI库一样,Android的UI也是线程不安全的。也就是说,如果想要更新应用中的UI元素,则必须在主线程中进行,否则就会出现异常。

  举个例子,新建一个AndroidThreadTest的项目,然后修改activity中的代码

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/change_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Change text"/>

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello world"
        android:textSize="20sp"/>

</RelativeLayout>

  布局文件中定义了两个控件,TextView用于在屏幕正中间显示一个Hello World字符串,Button用于改变TextView中显示的内容。我们希望在点击Button后可以把TextView中显示的字符串改成Nice to meey you.

  接下来修改MainActivity中的代码:

 1 public class MainActivity extends Activity implements OnClickListener{
 2
 3     private Button changeText;
 4     private TextView text;
 5
 6     @Override
 7     protected void onCreate(Bundle savedInstanceState) {
 8         super.onCreate(savedInstanceState);
 9         setContentView(R.layout.activity_main);
10         text = (TextView)findViewById(R.id.text);
11         changeText = (Button)findViewById(R.id.change_text);
12         changeText.setOnClickListener(this);
13     }
14
15     @Override
16     public boolean onCreateOptionsMenu(Menu menu) {
17         // Inflate the menu; this adds items to the action bar if it is present.
18         getMenuInflater().inflate(R.menu.main, menu);
19         return true;
20     }
21
22     @Override
23     public void onClick(View v) {
24         // TODO Auto-generated method stub
25         switch (v.getId()) {
26         case R.id.change_text:
27             new Thread(new Runnable() {
28
29                 @Override
30                 public void run() {
31                     // TODO Auto-generated method stub
32                     text.setText("Nice to meet you");
33                 }
34             }).start();
35             break;
36
37         default:
38             break;
39         }
40     }
41
42 }

  可以看到,在change text按钮的点击事件中开启了一个子线程,然后在子线程中调用TextView的setText()方法去改变字符串,代码的逻辑非常简单,但是就是按下按钮然后更新文本,然后运行一下程序,可以发现程序不出所料的将会崩溃。

  程序崩溃的原因是因为在子线程中更新UI所导致的,由此可以看到Android不允许在子线程进行UI操作。但有些时候我们必须在子进程中去执行一些耗时任务,然后根据任务的执行结果来更新相应的UI控件,对于这种情况,就需要使用Android提供的一套异步消息处理机制了。

时间: 2024-08-03 11:28:46

Android多线程编程(一)——多线程基础的相关文章

多线程编程之线程基础

前言 此内容是阅读了书籍<JAVA多线程编程核心技术>后作为学习总结的文章,同时也梳理一下内容.建议大家有兴趣都可以阅读一下这本书,对于想了解更多的同学来说是一个很好的教材,同时建议大家多去思考和动手编写代码,融会贯通之后再去看一遍,会有更多的体会.就比如<JVM底层实现最佳实战>的书籍一样,我读了已经不下五遍了,但每次读都能有新的收获一样.希望对大家有帮助. 该篇文章是用于了解多线程的一些基本概念.JDK支持多线程编程的类和方法,接口等. 1.1 进程与线程概念 什么是进程: 进

java多线程编程(一基础概念)

1.进程和线程       进程,是一个正在运行的程序实体,windows下常见的就是xxx.exe,在任务管理器中可以看见很多个进程.它是线程的容器. 线程,是进程中的一个执行流.在单线程编程中,我们的程序只有一个执行流:主线程的main方法.流,表明执行的过程是有顺序的,如main函数中的语句需要一条一条的按顺序执行,第一条语句没执行完,就不能去执行第二条语句. 可见,单线程编程是有限制的,那就是我们的语句只能串行执行,不可能发生某些语句同时执行的现象.有时我们希望某些代码并行执行,就好比我

Python多线程编程之多线程加锁

Python语言本身是支持多线程的,不像PHP语言. 下面的例子是多个线程做同一批任务,任务总是有task_num个,每次线程做一个任务(print),做完后继续取任务,直到所有任务完成为止. 1 #coding:utf-8 2 import threading 3 4 start_task = 0 5 task_num = 10000 6 mu = threading.Lock() ###通过工厂方法获取一个新的锁对象 7 8 class MyThread(threading.Thread):

Delphi多线程编程(8)--多线程同步之CriticalSection(临界区)

转载自:万一的博客 先看一段程序 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1=class(TForm) ListBox1: TListBox; Button1: TButton; procedure FormCreate(Sender: TObject); procedure

Java 多线程编程之多线程定义和多线程状态

一.定义线程 1.扩展java.lang.Thread类. 此类中有个run()方法,应该注意其用法: public void run() java.lang 类 Thread java.lang.Object java.lang.Thread 所有已实现的接口: Runnable public class Thread  extends Object implements Runnable 如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方

Delphi多线程编程(12)--多线程同步之Semaphore(信号对象)

转载自:万一的博客 之前已经有了两种线程同步的方法: CriticalSection(临界区)和Mutex(互斥)吗,这两种同步方法差不多,只是作用域不同 CriticalSection类似于只有一个蹲位的公共厕所,只能一个个地进 Mutex 对象类似于接力赛中的接力棒,某一时刻只能有一个人持有,谁拿着谁跑 什么是Semaphore(信号或叫信号量)呢? 譬如到银行办业务.或者到车站买票,原来只有一个服务员,不管有多少人排队等候,业务只能一个个地来 假如增加业务窗口,可以同时受理几个业务呢? 这

Delphi多线程编程(10)--多线程同步之Mutex(互斥对象)

原理分析: 互斥对象是系统内核对象,各个线程都可以拥有它,谁拥有它谁就可以执行 执行完毕,用ReleaseMutex 函数释放拥有权,以让其他等待的线程可以使用 其他线程可以使用 WaitForSingleObject函数排队等待(等待也可以理解为排队申请) 使用过程 var hMutex: THandle; {应该先声明一个全局的互斥句柄} CreateMutex {建立互斥对象} WaitForSingleObject {用等待函数排队等候} ReleaseMutex {释放拥有权} Clo

Delphi多线程编程(15)--多线程同步之WaitableTimer(等待定时器对象)[续]

转载自:万一的博客 本次专门研究下 SetWaitableTimer的第二个参数(起始时间) 它有正值.负值.0值这三种情况,前面已经用过 0 值 先学习负值(相对时间),也就是从当前算起隔多长时间开始执行 这个相对时间是以 1/100 纳秒为单位的,譬如赋值:3*10000000 相当于 3 秒 1 s(秒) = 1,000            ms(毫秒); 1 s(秒) = 1,000,000        µs(微妙); 1 s(秒) = 1,000,000,000    ns(纳秒)

Delphi多线程编程(14)--多线程同步之WaitableTimer(等待定时器对象)

转载自:万一的博客 function CreateWaitableTimer( lpTimerAttributes: PSecurityAttributes; //安全 bManualReset: BOOL; //True:可调度多个线程:False:只调度一个线程 lpTimerName: PWideChar //名称 ):THandle; stdcall; //返回句柄 function SetWaitableTimer( hTime: THandle; //句柄 var lpDueTime

iOS开发之多线程编程

iOS开发之多线程编程 1. 多线程简述 1.1什么是多线程? 解决的问题? 多线程是指,编程中在主线程之外开辟的新线程,用于处理一些耗时的.并发的任务.使用多线程可以避免主线程的阻塞,也对一个线程不容易实现的任务提供了思路.在多线程的知识中也涉及队列,锁等概念. 在这里科普一下队列的概念,队列:是管理线程的,相当于线程池,能管理线程什么时候执行.队列分为串行队列和并行队列. 串行队列:队列中的线程按顺序执行(不会同时执行) 并行队列:队列中的线程会并发执行,可能会有一个疑问,队列不是先进先出吗