您的位置:首页 > 移动开发 > Android开发

Android学习——定时执行,线程,线程池

2015-10-25 23:41 549 查看
今天主要内容:

 Time

 定时管理:android中AlarmManager

java中Time + TimerTask

 线程,线程池:java中ExecutorService ,继承Thread或实现Runnable接口

android中AsyncTask

Thread + Handler

1. Time类

// 实例化Time对象
Time time = new Time();
// 设置当前时间,默认是格林尼治时间
time.setToNow();
System.out.println(time);
// 获取当前时区
System.out.println(Time.getCurrentTimezone());
// 输出当前日期、时间
System.out.println(time.year + "年" + time.month + "月" + time.monthDay + "日" + time.hour + "时" + time.minute
+ "分" + time.second + "秒" + ":现在是一年中的第" + time.yearDay + "天");
// 获取当前是一年中的第几周
System.out.println("现在是一年中的第" + time.getWeekNumber() + "周");
// 日期的格式化输出
System.out.println(time.format("%Y-%m-%d %H:%M:%S"));
System.out.println(time.format2445());
System.out.println(time.format3339(true));
System.out.println(time.format3339(false));

// 把字符串2015-05-05解析为一个日期
time.parse3339("2015-05-05");
System.out.println(time.year);


运行结果:



定时管理

2.1 Android中定时管理——AlarmManager

创建2个广播接收者Reciver1:弹出吐司通知;Reciver2:弹出一个DemoActivity.

public class Reciver1 extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Reciver1", 0).show();
}
}


public class Reciver2 extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
intent = new Intent(context,DemoActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}

}


public class DemoActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Button button = new Button(this);
button.setText("hello");
this.setContentView(button);
}
}


在清单文件中注册:

<activity android:name=".DemoActivity"></activity>
<receiver android:name=".Reciver1">
<intent-filter >
<action android:name="www.humour.reciver1"/>
</intent-filter>
</receiver>
<receiver android:name=".Reciver2">
<intent-filter >
<action android:name="www.humour.reciver2"/>
</intent-filter>
</receiver>


MainAcitvity:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取AlarmManager系统服务
AlarmManager alarmManager = (AlarmManager) this.getSystemService(ALARM_SERVICE);

Intent intent1 = new Intent("www.humour.reciver1");
Intent intent2 = new Intent(("www.humour.reciver2"));
PendingIntent pIntent1 = PendingIntent.getBroadcast(this, 0, intent1, 0);
PendingIntent pIntent2 = PendingIntent.getBroadcast(this, 1, intent2, 0);
//设置重复闹铃
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,              SystemClock.currentThreadTimeMillis()+3000,25000,pIntent1);
//设置单次闹铃
alarmManager.set(AlarmManager.RTC_WAKEUP,
SystemClock.currentThreadTimeMillis()+3000, pIntent2);
}


2.2 Java中定时管理——Timer,TimerTask

public class JavaTimer {

public static void main(String[] args) {

TimerTask timerTask = new MyTask();
Timer timer = new Timer();
//5秒之后启动,每隔1秒执行一次

timer.schedule(timerTask, 5000, 1000);
System.out.println("main end");
}

static class MyTask extends TimerTask {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

public MyTask() {
}

@Override
public void run() {
System.out.println(sdf.format(new Date()));
}

}
}


执行结果:



线程,线程池

3.1 线程

1)实现Runnable接口 + Handler

——子线程发消息给主线程,由主线程去处理

功能:点击开始按钮,进度条开始,到100时弹出“Over”提示。



(1)布局文件中添加5个ProgressBar:

<LinearLayout 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:orientation="vertical"
tools:context="${relativePackage}.${activityClass}" >

<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="start"
android:text="开始" />

<ProgressBar
android:id="@+id/pb1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100" />

<ProgressBar
android:id="@+id/pb2"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100" />

<ProgressBar
android:id="@+id/pb3"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100" />

<ProgressBar
android:id="@+id/pb4"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100" />

<ProgressBar
android:id="@+id/pb5"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100" />

</LinearLayout>


(2)使用Runnable, Handler:

java代码:

public class MainActivity extends Activity {
private ProgressBar pb;
//主线程处理接收到的消息,更新界面显示
private Handler handler= new Handler(){
public void handleMessage(android.os.Message msg) {
if(msg.what == 1){
pb.setProgress(msg.arg1);
//进度为100时,弹出结束提示
if(msg.arg1 == 100){
Toast.makeText(MainActivity.this, "Over", 0).show();
}
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pb = (ProgressBar)this.findViewById(R.id.pb1);
}

public void start(View view) {
//单击开始按钮,开启子线程
Runnable runnable = new ProgressBarRunnable(pb);
new Thread(runnable).start();
}
//子线程处理
class ProgressBarRunnable implements Runnable{
private ProgressBar pb;
public ProgressBarRunnable(ProgressBar pb) {
this.pb = pb;
}
@Override
public void run() {
for(int i=0;i<100;i++){
SystemClock.sleep(50);
//向主线程发送消息
Message msg = handler.obtainMessage();
msg.what = 1;
msg.arg1 = i;
handler.sendMessage(msg);
}
}
}

}


2) 异步任务AsyncTask(UI变化)——android特有的

上面的功能也可以使用AsyncTask来完成

异步任务AsyncTask是对线程的封装,实际和线程是一回事。

最简单的写法:

AsyncTask.execute(new Runnable(){

public void run(){

}

});

继承AsyncTask:

onPreExecute:线程开始之前执行

onPostExecute:线程完成之后执行

doInBackground:只有此方法是在子线程中执行的publishProgress

onProgressUpdate:更新进度pb.setProgress(values[0])

代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pb = (ProgressBar)this.findViewById(R.id.pb1);
System.out.println(Process.myPid()+"    "+Process.myTid()+"    "+Process.myUid()+"----onCreate");

}
public void start(View view) {
//单击开始按钮,开启子线程
new ProgressBarAsyncTask(pb).execute("xxx");
}
class ProgressBarAsyncTask extends AsyncTask<String, Integer, String>{
private ProgressBar pb;

public ProgressBarAsyncTask(ProgressBar pb) {
super();
this.pb = pb;
}
//后台操作
@Override
protected String doInBackground(String... params) {
System.out.println(Process.myPid()+"    "+Process.myTid()+"    "+Process.myUid()+"----doInBackground");
for(int i=0;i<100;i++){
SystemClock.sleep(50);
//发布线程
publishProgress(i);
}
return "Over";
}
//线程开始之前执行
@Override
protected void onPreExecute() {
System.out.println(Process.myPid()+"    "+Process.myTid()+"    "+Process.myUid()+"----onPreExecute");
super.onPreExecute();
pb.setProgress(0);
}
//线程结束之后执行
@Override
protected void onPostExecute(String result) {
System.out.println(Process.myPid()+"    "+Process.myTid()+"    "+Process.myUid()+"----onPostExecute");
super.onPostExecute(result);
Toast.makeText(MainActivity.this, result, 0).show();
}
//更新界面的操作
@Override
protected void onProgressUpdate(Integer... values) {
System.out.println(Process.myPid()+"    "+Process.myTid()+"    "+Process.myUid()+"----onProgressUpdate");
super.onProgressUpdate(values);
pb.setProgress(values[0]);
}

}


在方法中分别打印PID,TID,UID,如下:

进程ID  线程ID   用户ID






从图中可以看出,doInBackground是单独一个线程,整个应用程序是一个进程,所以进程id相同。

AsyncTask<String, Integer, String>泛型所起的作用:
new ProgressBarAsyncTask(pb).execute("xxx")--------第一个泛型String
String doInBackground(String... params)------------第一个泛型String
onProgressUpdate(Integer... values)----------------第二个泛型Integer
void onPostExecute(String result)-------------doInBackground返回类型String,传给此方法作为参数 ,第三个泛型String


3.2 线程池

1)Android中AsyncTask自带线程池

功能:让5个Progress都执行

private final int NUM = 5;
private int[] ids = new int[NUM];
private ProgressBar[] progressBars = new ProgressBar[NUM];

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (int i = 0; i < NUM; i++) {
ids[i] = this.getResources().getIdentifier("pb" + (i + 1), "id", this.getPackageName());
progressBars[i] = (ProgressBar) this.findViewById(ids[i]);
}
public void start(View view) {
// 单击开始按钮,开启子线程
for (ProgressBar pb : progressBars) {
new ProgressBarAsyncTask(pb).execute();
}
}


运行结果:一个进度条从0走到100,下一个进度条才开始,一个子线程执行完了再开启下一个子线程

//使用线程池管理子线程

private ExecutorService es = Executors.newFixedThreadPool(5);

public void start(View view) {

// 单击开始按钮,开启子线程

for (ProgressBar pb : progressBars) {

//new ProgressBarAsyncTask(pb).execute();

ProgressBarAsyncTask pbat = new ProgressBarAsyncTask(pb);

pbat.executeOnExecutor(es, null);

}

}

运行结果:点击开始按钮后,5个进度条同时执行。

2)java中线程池——ExecutorService或者Executor

ExecutorService executor = Executors.newSingleThreadExecutor();//单个线程

newFixedThreadPool(2);//固定个数的线程池

newCacheThreadPool();//有几个线程线程池就多大

executor.execute(new MyRun());不用调用start开始

shutdown();//已经添加的线程继续执行完,之后的线程无法继续添加

shutdownNow();//建议阻塞状态的线程终止,后续线程无法添加

(1)ExecutorService executor = Executors.newSingleThreadExecutor();//单个线程

线程池中只有一个线程:

public class JavaPools {
//线程池中只有一个线程
ExecutorService es = Executors.newSingleThreadExecutor();
//线程池中固定个数的线程,2个
//ExecutorService es = Executors.newFixedThreadPool(2);
//有几个线程,线程池就有多大
//ExecutorService es = Executors.newCachedThreadPool();
public JavaPools() {
for(int i = 0; i<3; i++){
es.execute(new MyRun());
if (i==1) {
es.shutdown();
//es.shutdownNow();
}
}

}
public static void main(String[] args) {
new JavaPools();
}
class MyRun implements Runnable{

@Override
public void run() {
for(int i=0;i<4;i++){
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("over...............................");
}

}
}


输出结果如下:



说明:线程池中只有一个线程,一个子线程执行结束后再执行下一个,子线程的名字是相同的。

(2)newFixedThreadPool(2);//固定个数的线程池

执行结果:



说明:因为线程池中只有两个线程,所以前两个线程执行完之后,第三个线程才开始执行。

(3)newCacheThreadPool();//有几个线程,线程池就多大

执行结果:



说明:三个子线程同时执行。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: