本期讲的是个人对于Service的浅显的见解。主要就是简单的给大家讲一下怎么用Service。
Service是Android的四大组件之一,在app应用中也是比较频繁。简单的说Activity是可以显示给用户看的。Service是不给用户看但是他俩没有本质上区别的。而且他们两个是在一个线程中的。请看下面示例:
在MainActivity的onCreate中执行Log可以看到线程序号
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.e("---------------------", "MainActivity thread id is " + Thread.currentThread().getId()); }
在Service的onCreate中写
@Override public void onCreate() { super.onCreate(); Log.e("----------------", "MyService thread id is " + Thread.currentThread().getId()); }
执行结果是
androidservicetest E/---------------------: MainActivity thread id is 1
androidservicetest E/----------------: MyService thread id is 1
MainActivity
public class MainActivity extends AppCompatActivity { Intent intent; SecondSrevice.MyBinder myBinder; ServiceConnection conn=new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { myBinder= (SecondSrevice.MyBinder) service; myBinder.startrun(); } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.e("---------------------", "MainActivity thread id is " + Thread.currentThread().getId()); } public void oneopenservice(View view){ intent=new Intent(this, FirstService.class); startService(intent); } public void onecloseservice(View view){ intent=new Intent(this, FirstService.class); stopService(intent); } public void oneopenservicetop(View view){ intent=new Intent(this, TopService.class); startService(intent); } public void onecloseservicetop(View view){ intent=new Intent(this, TopService.class); stopService(intent); } public void twoopenservice(View view){ intent=new Intent(this, SecondSrevice.class); bindService(intent,conn,BIND_AUTO_CREATE); } public void twocloseservice(View view){ unbindService(conn); } public void openintentservice(View view){ startService(new Intent(this, MyIntentService.class)); } }
FirstService
public class FirstService extends Service{ private Timer timer; private TimerTask timerTask; @Override public void onCreate() { super.onCreate(); Log.e("----------------", "MyService thread id is " + Thread.currentThread().getId()); } @Override public int onStartCommand(Intent intent, int flags, int startId) { if(timer!=null&&timerTask!=null){ timer.cancel(); timerTask.cancel(); timer=null; timerTask=null; } timer=new Timer(); timerTask=new DoTimeTask(); long period=1000*5; Calendar calendar=Calendar.getInstance(); Date firsttime=calendar.getTime(); timer.schedule(timerTask,firsttime,period); return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { super.onDestroy(); if(timer!=null&&timerTask!=null){ timer.cancel(); timerTask.cancel(); timer=null; timerTask=null; } } }
SecondServcie
public class SecondSrevice extends Service{ private Timer timer; private TimerTask timerTask; private MyBinder myBinder=new MyBinder(); @Override public IBinder onBind(Intent intent) { return myBinder; } public class MyBinder extends Binder{ public void startrun(){ if (timer!=null&&timerTask!=null) { timer.cancel(); timerTask.cancel(); timer=null; timerTask=null; } timer=new Timer(); timerTask=new DoTimeTask(); Calendar calendar=Calendar.getInstance(); Date firsttime=calendar.getTime(); long period=1000*5; timer.schedule(timerTask,firsttime,period); } } @Override public void onDestroy() { super.onDestroy(); if(timer!=null&&timerTask!=null){ timer.cancel(); timerTask.cancel(); timer=null; timerTask=null; } } }
TopService
public class TopService extends Service { private static final int NOTIFY_ID=123; @Override public void onCreate() { super.onCreate(); showNotification(); } public void showNotification(){ NotificationCompat.Builder builder=new NotificationCompat.Builder(this).setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("今天").setContentText("天气很好"); Intent resultintent=new Intent(this, SecondActivity.class); TaskStackBuilder stackBuilder=TaskStackBuilder.create(this); stackBuilder.addParentStack(MainActivity.class); stackBuilder.addNextIntent(resultintent); PendingIntent resultRending=stackBuilder.getPendingIntent(0,PendingIntent.FLAG_CANCEL_CURRENT); builder.setContentIntent(resultRending); NotificationManager notificationManager= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); Notification notification=builder.build(); notificationManager.notify(NOTIFY_ID,notification); startForeground(NOTIFY_ID,notification); } @Override public IBinder onBind(Intent intent) { return null; } }
MyIntentService
public class MyIntentService extends IntentService{ public MyIntentService() { super("MyIntentService"); } @Override protected void onHandleIntent(Intent intent) { DateFormat format= DateFormat.getTimeInstance(); Log.e("test", "onHandleIntent开始:" + format.format(new Date())); try{ Thread.sleep(5000); }catch (InterruptedException e){ } Log.e("test", "onHandleIntent完成:" + format.format(new Date())); } @Override public void onDestroy() { Log.e("intentservice","onDestory"); super.onDestroy(); } }
SecondActivity
public class SecondActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.second_activity); } }
activity_main
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:background="@drawable/shape_selector_btn" android:textColor="@drawable/button_font_style" android:onClick="oneopenservice" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" android:text="第一种启动服务模式"/> <Button android:background="@drawable/shape_selector_btn" android:textColor="@drawable/button_font_style" android:onClick="onecloseservice" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" android:text="第一种关闭服务模式"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:background="@drawable/shape_selector_btn" android:textColor="@drawable/button_font_style" android:onClick="oneopenservicetop" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" android:text="First启动服务模式之top"/> <Button android:background="@drawable/shape_selector_btn" android:textColor="@drawable/button_font_style" android:onClick="onecloseservicetop" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" android:text="First关闭服务模式之top"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <Button android:background="@drawable/shape_selector_btn" android:textColor="@drawable/button_font_style" android:onClick="twoopenservice" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" android:text="第二种启动服务模式"/> <Button android:background="@drawable/shape_selector_btn" android:textColor="@drawable/button_font_style" android:onClick="twocloseservice" android:layout_weight="1" android:layout_width="0dp" android:layout_height="wrap_content" android:text="第二种关闭服务模式"/> </LinearLayout> <Button android:background="@drawable/shape_selector_btn" android:textColor="@drawable/button_font_style" android:onClick="openintentservice" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="启动IntentService"/> </LinearLayout>
second_activity
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="天气不错"/> </LinearLayout>别忘了新建的Service要在配置文件中进行配置
<activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".SecondActivity"/> <service android:name=".service.FirstService"/> <service android:name=".service.SecondSrevice"/> <service android:name=".service.TopService"/> <service android:name=".service.MyIntentService"/>
第一种启动关闭方式是最常见的。一遍结合BroadCast使用进行跟activity的数据交互。第二种方式不常用,也是可以直接进行数据交互的。IntentService讲用户请求执行在一个子线程中用户只要通过复写onHandleIntent函数,并且在该函数中完成自己的耗时操作即可。在任务结束后,IntentService回调用stopself自我销毁。因此他比较适合一些短时的操作。TopService是运行在前台的srevice还可以实现点击功能。
下节将讲解两个app之间通过Service访问进程,即AIDL。
项目下载地址
https://github.com/Maliola/AndroidServiceTest