Android学习——定时执行,线程,线程池
2015-10-25 23:41
549 查看
今天主要内容:
Time
定时管理:android中AlarmManager
java中Time + TimerTask
线程,线程池:java中ExecutorService ,继承Thread或实现Runnable接口
android中AsyncTask
Thread + Handler
1. Time类
运行结果:
定时管理
2.1 Android中定时管理——AlarmManager
创建2个广播接收者Reciver1:弹出吐司通知;Reciver2:弹出一个DemoActivity.
在清单文件中注册:
MainAcitvity:
2.2 Java中定时管理——Timer,TimerTask
执行结果:
线程,线程池
3.1 线程
1)实现Runnable接口 + Handler
——子线程发消息给主线程,由主线程去处理
功能:点击开始按钮,进度条开始,到100时弹出“Over”提示。
(1)布局文件中添加5个ProgressBar:
(2)使用Runnable, Handler:
java代码:
2) 异步任务AsyncTask(UI变化)——android特有的
上面的功能也可以使用AsyncTask来完成
异步任务AsyncTask是对线程的封装,实际和线程是一回事。
最简单的写法:
AsyncTask.execute(new Runnable(){
public void run(){
}
});
继承AsyncTask:
onPreExecute:线程开始之前执行
onPostExecute:线程完成之后执行
doInBackground:只有此方法是在子线程中执行的publishProgress
onProgressUpdate:更新进度pb.setProgress(values[0])
代码:
在方法中分别打印PID,TID,UID,如下:
从图中可以看出,doInBackground是单独一个线程,整个应用程序是一个进程,所以进程id相同。
3.2 线程池
1)Android中AsyncTask自带线程池
功能:让5个Progress都执行
运行结果:一个进度条从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();//单个线程
线程池中只有一个线程:
输出结果如下:
说明:线程池中只有一个线程,一个子线程执行结束后再执行下一个,子线程的名字是相同的。
(2)newFixedThreadPool(2);//固定个数的线程池
执行结果:
说明:因为线程池中只有两个线程,所以前两个线程执行完之后,第三个线程才开始执行。
(3)newCacheThreadPool();//有几个线程,线程池就多大
执行结果:
说明:三个子线程同时执行。
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();//有几个线程,线程池就多大
执行结果:
说明:三个子线程同时执行。
相关文章推荐
- Android中获取地理位置经纬度
- Android学习——服务Service与广播接收者BroadcastReciver
- Android中获取CPU序列号
- Android Volley完全解析(一),初识Volley的基本用法
- Android 获取AndroidManifest.xml 中 meta-data 的值
- Android中自定义控件
- Android利用dimens.xml进行适配,使用代码生成不同的dimens.xml文件
- android 中使用AutoCompleteTextView 可以实现自动提示功能
- Android实现多个词汇连续输入的提示
- 关于android中搜索功能的实现
- Android:重写ViewPager实现Fragment的自由替换
- Android模块化编程之引用本地的aar
- OpenCV4android org.opencv.feature2d
- Android Support Design 控件 FloatingActionButton
- Android Support Design 控件 FloatingActionButton
- 对话框形式的activity
- 怎样在android中添加背景图片?
- android上使用opencv遇到的一点问题
- android Push 服务的消息
- Android:Using shared element transitions in fragments