Android线程的学习 之二
来源:互联网 发布:九洲盛世网络竞技杭州 编辑:程序博客网 时间:2024/06/04 08:40
在网上有很多文章讲述主线程和其他子线程如何交互,传送信息,最终谁来执行处理信息之类的,个人理解是最简单的方法——判断Handler对象里面的Looper对象是属于哪条线程的,则由该线程来执行! 1.当Handler对象的构造函数的参数为空,则为当前所在线程的Looper; 2. Looper.getMainLooper()得到的是主线程的Looper对象,Looper.myLooper()得到的是当前线程的Looper对象。 1) 子类化AsyncTask 2) 实现AsyncTask中定义的下面一个或几个方法 onPreExecute()开始执行前的准备工作; doInBackground(Params...)开始执行后台处理,可以调用publishProgress方法来更新实时的任务进度; onProgressUpdate(Progress...) 在publishProgress方法被调用后,UIthread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。 onPostExecute(Result)执行完成后的操作,传送结果给UI 线程。 这4个方法都不能手动调用。而且除了doInBackground(Params...)方法,其余3个方法都是被UI线程所调用的,所以要求: 1) AsyncTask的实例必须在UIthread中创建; 2) AsyncTask.execute方法必须在UIthread中调用; 同时要注意:该task只能被执行一次,否则多次调用时将会出现异常。而且是不能手动停止的,这一点要注意,看是否符合你的需求! 在使用过程中,发现AsyncTask的构造函数的参数设置需要看明白:AsyncTask<Params,Progress, Result> Params对应doInBackground(Params...)的参数类型。而newAsyncTask().execute(Params...params),就是传进来的Params数据,你可以execute(data)来传送一个数据,或者execute(data1,data2, data3)这样多个数据。 Progress对应onProgressUpdate(Progress...)的参数类型; Result对应onPostExecute(Result)的参数类型。 当以上的参数类型都不需要指明某个时,则使用Void,注意不是void。不明白的可以参考上面的例子,或者APIDoc里面的例子。
现在来看一个例子,模拟从网络获取数据,加载到ListView的过程:
- public
class ListProgressDemo extendsListActivity { -
-
@Override -
public void onCreate(Bundle savedInstanceState) { -
super.onCreate(savedInstanceState); -
setContentView(R.layout.listprogress); -
-
((Button) findViewById(R.id.load_Handler)).setOnClickListener(new View.OnClickListener(){ -
-
@Override -
public void onClick(View view) { -
data = null; -
data = new ArrayList<String>(); -
-
adapter = null; -
-
showDialog(PROGRESS_DIALOG); -
new ProgressThread(handler, data).start(); -
} -
}); -
} -
-
@Override -
protected Dialog intonCreateDialog( id) { -
switch(id) { -
case PROGRESS_DIALOG: -
return ProgressDialog.show( this,"", -
"Loading. Please ,wait..." true); -
-
default: return null; -
} -
} -
-
private class ProgressThread extendsThread { -
-
private Handler handler; -
private ArrayList<String> data; -
-
public ProgressThread(Handler handler, ArrayList<String> data) { -
this.handler = handler; -
this.data = data; -
} -
-
@Override -
public void run() { -
for ( inti= 0;i< 8;i++) { -
data.add("ListItem"); //后台数据处理 -
try { -
Thread.sleep(100); -
}catch(InterruptedException e) { -
-
Message msg = handler.obtainMessage(); -
Bundle b = new Bundle(); -
b.putInt("state", STATE_ERROR); -
msg.setData(b); -
handler.sendMessage(msg); -
-
} -
} -
Message msg = handler.obtainMessage(); -
Bundle b = new Bundle(); -
b.putInt("state", STATE_FINISH); -
msg.setData(b); -
handler.sendMessage(msg); -
} -
-
} -
-
此处甚至可以不需要设置Looper,因为Handler默认就使用当前线程的Looper -
private final Handler newhandler = Handler(Looper.getMainLooper()) { -
-
public void handleMessage(Message msg) { -
int state "state");= msg.getData().getInt( -
switch(state){ -
case STATE_FINISH: -
dismissDialog(PROGRESS_DIALOG); -
Toast.makeText(getApplicationContext(), -
"加载完成!", -
Toast.LENGTH_LONG) -
.show(); -
-
adapter = new ArrayAdapter<String>(getApplicationContext(), -
android.R.layout.simple_list_item_1, -
data ); -
-
setListAdapter(adapter); -
-
break; -
-
case STATE_ERROR: -
dismissDialog(PROGRESS_DIALOG); -
Toast.makeText(getApplicationContext(), -
"处理过程发生错误!", -
Toast.LENGTH_LONG) -
.show(); -
-
adapter = new ArrayAdapter<String>(getApplicationContext(), -
android.R.layout.simple_list_item_1, -
data ); -
-
setListAdapter(adapter); -
-
break; -
-
default: -
-
} -
} -
}; -
-
-
private ArrayAdapter<String> adapter; -
private ArrayList<String> data; -
-
private static final int PROGRESS_DIALOG 1;= -
private static final int STATE_FINISH 1;= -
private static final int STATE_ERROR 1;= - - }
这个例子,我自己写完后觉得还是有点乱,要稍微整理才能看明白线程间交互的过程以及数据的前后变化。随后了解到AsyncTask类,相应修改后就很容易明白了!
2.3 AsyncTask
AsyncTask版:
- ((Button)
findViewById(R.id.load_AsyncTask)).setOnClickListener( newView.OnClickListener(){ -
-
@Override -
public void onClick(View view) { -
data = null; -
data = new ArrayList<String>(); -
-
adapter = null; -
-
//显示ProgressDialog放到AsyncTask.onPreExecute()里 -
//showDialog(PROGRESS_DIALOG); -
new ProgressTask().execute(data); -
} - });
-
- private
class ProgressTask extendsAsyncTask<ArrayList<String>, Void, Integer> { -
-
- @Override
- protected
void onPreExecute() { -
// 先显示ProgressDialog -
showDialog(PROGRESS_DIALOG); - }
-
-
- @Override
- protected
Integer doInBackground(ArrayList<String>... datas) { -
ArrayList<String> data = datas[0]; -
for ( inti= 0;i< 8;i++) { -
data.add("ListItem"); -
} -
return STATE_FINISH; - }
-
-
- @Override
- protected
void onPostExecute(Integer result) { -
int state = result.intValue(); -
switch(state){ -
case STATE_FINISH: -
dismissDialog(PROGRESS_DIALOG); -
Toast.makeText(getApplicationContext(), -
"加载完成!", -
Toast.LENGTH_LONG) -
.show(); -
-
adapter = new ArrayAdapter<String>(getApplicationContext(), -
android.R.layout.simple_list_item_1, -
data ); -
-
setListAdapter(adapter); -
-
break; -
-
case STATE_ERROR: -
dismissDialog(PROGRESS_DIALOG); -
Toast.makeText(getApplicationContext(), -
"处理过程发生错误!", -
Toast.LENGTH_LONG) -
.show(); -
-
adapter = new ArrayAdapter<String>(getApplicationContext(), -
android.R.layout.simple_list_item_1, -
data ); -
-
setListAdapter(adapter); -
-
break; -
-
default: -
-
} - }
----------------
本文的相当内容摘录于《浅析Android线程模型一 ---转》,但对于Message机制的流程理解则在参考《android中Message机制的灵活应用》后修改了!
转至 http://android.blog.51cto.com/268543/343823
0 0
- Android线程的学习 之二
- Android线程的学习 之一
- Android线程学习(二)之ExecutorService
- Android NDK学习之环境配置入门二
- Java学习笔记之线程(二):线程的常用方法
- Android学习之线程
- Android JNI开发入门之二
- Android JNI开发入门之二
- android学习之 如何在当前的Activi…
- Android : 线程的结束,挂起…
- [android基础知识] 之二: 任务、进程和线程的区别
- Android之Handler子线程的简单使用(二)
- android多线程之二:终止线程的三种方法
- C++ 学习 二
- Android NDK学习之 环境搭建-下载…
- android学习之State List
- Android Service学习之IntentServi…
- android Service学习之本地服务
- Drawable(hdpi,ldpi,mdpi)目录的区…
- Nginx反向代理关于端口的问题
- Android permission 访问权限大全
- 互联网周刊:草根创业选择题
- Android线程的学习 之一
- Android线程的学习 之二
- 《程序员》9月刊推荐:移动应用产…
- 自定义含有进度条Dialog
- android中的图形图像处理-如访问图片drawable
- 树莓派脚本,开机自启动
- AsyncTask例子之一
- 手机开发平台汇总
- 十年编程经验凝结 与新人们分享
- velocity技术实现页面静态化