1)回顾java多线程基础
Runnable
Thread
ThreadPoolExecutor
ScheduleExecutor
线程同步(Synchronized、Lock、Semaphore)
2)在Android中使用多线程
a、为何使用多线程
io操作(文件操作、网络操作、数据库操作)
复杂运算
定时操作(如dialog显示后5秒钟后消失)
对于耗时的操作,我们应该放到非主线程中运行,从而避免阻塞主线程。
为了保证良好的用户体验,建议对超过50ms的操作,都使用线程处理。
b、如何使用多线程或异步操作
Thread
Handler
AsyncTask
AsyncTaskLoader(android3.0后)
c、多线程和界面交互
Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelay(Runnable, long)
Handler
AsyncTask
Android UI主线程简单原则(不要Block UI Thread,不要在UI线程外直接操作UI,操作UI组件的必须在UI线程中操作)
代码说明
1.定义layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView android:id="@+id/imageView_display"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button android:id="@+id/button_thread01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="线程1"/>
<Button android:id="@+id/button_thread02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="线程2"/>
<Button android:id="@+id/button_thread03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="线程3"/>
<Button android:id="@+id/button_asyncTask"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="异步线程"/>
</LinearLayout>
2.JAVA代码实现
package com.douzi.treaddemo;
import java.io.IOException;
import java.net.URL;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView imageView = null;
private static final String IMAGE_URL_I = "https://www.sqlite.org/images/sqlite370_banner.gif" ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView)findViewById(R.id.imageView_display);
//直接在主线程中下载主线程会遇到线程阻塞的情况
Button button01 = (Button)findViewById(R.id.button_thread01);
button01.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Drawable drawable = loadImageFromNetwork(IMAGE_URL_I);
imageView.setImageDrawable(drawable);
}
});
Button button02 = (Button)findViewById(R.id.button_thread02);
//在一个新线程中,但主线程不是线程安全的
button01.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
Drawable drawable = loadImageFromNetwork(IMAGE_URL_I);
imageView.setImageDrawable(drawable);
}
}).start() ;
}
});
//在一个新的线程中,并使用imageView.post(Runnable);使线程与主UI线程分离
Button button03 = (Button)findViewById(R.id.button_thread03);
button01.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
final Drawable drawable = loadImageFromNetwork(IMAGE_URL_I);
imageView.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
imageView.setImageDrawable(drawable);
}
});
}
}).start() ;
}
});
//使用异步任务更加简洁
Button asyncTaskButton = (Button)findViewById(R.id.button_asyncTask);
asyncTaskButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new DownloadImageTask().execute(IMAGE_URL_I);
}
});
}
private class DownloadImageTask extends AsyncTask<String, Void, Drawable>{
@Override
protected Drawable doInBackground(String... params) {
// TODO Auto-generated method stub
return loadImageFromNetwork(params[0]);
}
/* (non-Javadoc)
* @see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
@Override
protected void onPostExecute(Drawable result) {
// TODO Auto-generated method stub
imageView.setImageDrawable(result);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private Drawable loadImageFromNetwork(String imageUrl){
Drawable drawable = null ;
try {
drawable.createFromStream(new URL(imageUrl).openStream(), "image.gif") ;
} catch (IOException e) {
// TODO Auto-generated catch block
Log.i("douzi", "加载图片失败" + e.getMessage()) ;
e.printStackTrace();
}
if (null == drawable){
Log.i("douzi", "没有Drawable") ;
}else{
Log.i("douzi", "有Drawable") ;
}
return drawable ;
}
}