android 多线程 异步消息处理 服务 学习笔记 (六)
三种多线程编程方法
1 class Mythread extends Thread{ @Override public void run(){} } new Mythread().start() 2 class Mythread implements Runnable{ @Override public void run(){} } Mythread myThread=new Mythread(); new Thread(myThread).start(); 3 new Thread{new Runnable{ @Override public void run(){} }.start();
异步消息处理机制(使用message更新ui)
public class MainActivity extends Activity implements OnClickListener{ Button button; TextView text; public static final int change=1; private Handler handler=new Handler(){ public void handleMessage(Message ms){ switch(ms.what){ case change: text.setText("nice to meet you"); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button=(Button) findViewById(R.id.change_Button); text=(TextView)findViewById(R.id.text); button.setOnClickListener(this); } public void onClick(View v){ switch (v.getId()) { case R.id.change_Button: new Thread(new Runnable(){ public void run(){ Message ms=new Message(); ms.what=change; handler.sendMessage(ms); } }).start(); break; default: break; } } }
使用AsynvTask更新ui
class DownloadTask extends AsyncTask<Void,Integer,Boolean>{ @Override protected void onPreExecute(){ progressDialog.show(); } @0verride protected Boolean doInBackground(Void...params){ try{ while(true){ int downloadPercent=doDownload(); publishProgress(downloadPercent); if(downloadPercent>=100){ break; } } }catch(Exception e){ return false; } return true; } protected void onProgressUpdate(Integer...values){ progressDialog.setMessage("Download"+values[0]+"%"); } @Override protected void onPostExecute(Boolean result){ progressDialog.dismiss(); if(result){ Toast.makeText(context,"Download succeeded",Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(context,"Download failed",Toast.LENGTH_SHORT).show(); } } }
定义一个服务
服务定义完成后要使用的话必须同android其他三大组件一样在manifest中注册才行 <service android:name=".MyService"></service>
在活动中启动或停止服务的话使用intent
Intent intent=new Intent(this,Myservice.class);
startService(intent);
Intent intent1=new Intent(this,Myservice.class);
stopService(intent1);或者是在服务的定义中调用stopSelf()来停止服务
public class MyService extends Service{ public IBinder onBind(Intent intent){ return null; } public void onCreate(){ super.onCreate(); } public int onStartCommand(Intent inten,int flags,int startId){ return super.onStartCommand(intent,flags,startId); } public void onDestroy(){ super.onDestroy(); } }
活动和服务进行通信:使用onBind()
public class MyService extends Service{ private DownloadBinder mBinder=new DownloadBinder(); class DownloadBinder extends Binder{ public void startDownload(){ Log.d("MyService","startdownload"); } public int getProgress(){ Log.d("MyService","getProgress") return 0 } } public IBinder onBind(Intent intent){ return mBinder; } } 主活动中调用 先建立一个ServieceConnection匿名类 private ServiceConnection connection=new ServiceConnection(){ public void onServiceDisconnected(ComponentName name){} public void onServiceConnected(ComponentName name,IBinder service){ MyService.DownloadBinder downloadBinder=(MyService.DownloadBinder)service;获得一个DownloadBinder实例 downloadBinder.startDownload(); downloadBinder.getProgress(); } } Intent bindintent=new Intent(this,MyService.class); bindService(bindintent,connection,BIND_ANTO_CREATE);绑定服务并且绑定后自动创建 。。 unbinderService(connection);解绑,connection为前面定义的ServiceConnection实例 注意服务在任何活动中都是通用的 可以和任何activity 进行绑定
使用intentService(可以自己开启线程并且可以自动停止)
定义:
public class MyIntentService extends IntentService { public MyIntentService( ) { super("MyIntentService"); // TODO Auto-generated constructor stub } protected void onHandleIntent(Intent intent){ Log.d("MyIntentService","thread id id"+Thread.currentThread().getId()); } public void onDestroy(){ super.onDestroy(); Log.d("MyIntentService","ondestroy exe"); } } 在活动中启动或者的方法是一样的 Intent intentService=new Intent(this,MyIntentService.class); startSercice(intentService); 同样要进行注册注册方法和普通服务一样的
服务的最佳实践 定时循环开启一项服务:
public class LongRunningService extends Service { public IBinder onBind(Intent intent){ return null; } public int onStartCommand(Intent intent,int flags,int startId){ new Thread(new Runnable(){ public void run(){ Log.d(".",""); } }).start(); AlarmManager manager=(AlarmManager)getSystemService(ALARM_SERVICE); int anHour=60*60*1000; long triggerAtTime=SystemClock.elapsedRealtime()+anHour; Intent i=new Intent(this,AlarmReceiver.class); PendingIntent pi=PendingIntent.getBroadcast(this,0,i,0); manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,triggerAtTime,pi); return super.onStartCommand(intent, flags, startId); } } 定义一个广播接收器 public class AlarmReceiver extends BroadcastReceiver{ public void onReceive(Context context,Intent intent){ Intent i=new Intent(context,LongRunningService.class); context.startService(i); } } 在活动中进行启动这个服务 一旦启动就会不断重复 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent=new Intent(this,LongRunningService.class); startService(intent); } 注意 :现在的手机当中为了省电,当存在多个Alarm定时任务的时候,他会 把时间相近的几个任务集合在一起去唤醒cpu,所以会有一些时间上的误差,为了准确无误,可以 把服务中manager.set()改为manager.setExact()