简单记录一下四大组件之一的Service的简单实用。
先是最简单的用法,服务的开关,onBind方法的使用
package com.example.wkp.service; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { private Button start=null; private Button stop=null; private Button bind=null; private Button unbind=null; private Button get=null; private MyService.MyBinder binder; private ServiceConnection connection=new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { //得到返回值binder binder= (MyService.MyBinder) service; //使用binder中的方法 Log.v("qq",String.valueOf(binder.getNum())); } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); start= (Button) findViewById(R.id.start); stop=(Button)findViewById(R.id.stop); bind=(Button)findViewById(R.id.bind); unbind=(Button)findViewById(R.id.unbind); get=(Button)findViewById(R.id.getnum); final Intent intent=new Intent(); //跳转到配置文件中定义的intent-filter // intent.setAction("SERVICE"); // intent.setPackage(getPackageName()); intent.setClass(MainActivity.this,MyService.class); start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startService(intent); } }); stop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { stopService(intent); } }); bind.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { bindService(intent,connection,BIND_AUTO_CREATE); } }); unbind.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { unbindService(connection); } }); get.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { Log.v("qq",String.valueOf(binder.getNum())); } }); // class btnListener implements View.OnClickListener{ // // @Override // public void onClick(View v) { // switch(v.getId()){ // case R.id.bind: // bindService(intent,connection,BIND_AUTO_CREATE); // break; // case R.id.unbind: // unbindService(connection); // break; // case R.id.getnum: // Log.v("qq",String.valueOf(binder.getNum())); // break; // default: // break; // } // } // } } }
package com.example.wkp.service; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.support.annotation.Nullable; import android.util.Log; import android.widget.Button; /** * Created by wkp on 2016/9/22. */ public class MyService extends Service { int num=0; MyBinder binder=new MyBinder(); @Nullable @Override public IBinder onBind(Intent intent) { Log.v("oo","binder"); return binder; } @Override public void onCreate() { super.onCreate(); Log.v("hehe","service create"); num+=10; } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); Log.v("hehe","service start"); } @Override public void onDestroy() { super.onDestroy(); Log.v("hehe","service destory"); } //创建一个Binder,用来在onBind中返回 class MyBinder extends Binder{ int getNum(){ return num; } } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.wkp.service.MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> <Button android:id="@+id/start" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="start"/> <Button android:id="@+id/stop" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="stop"/> <Button android:id="@+id/bind" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="bind"/> <Button android:id="@+id/unbind" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="unbind"/> <Button android:id="@+id/getnum" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="getnum"/> </LinearLayout>
在AndroidManifest.xml中注册服务
然后是前台服务和IntentService。就是手机屏幕左上角弹出来的小图标,和广播结合有点类似推送。
package com.example.wkp.service; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; /** * Created by wkp on 2016/9/24. */ public class SecondActivity extends Activity { private Button startFore=null; private Button stopFore=null; private Button startIntent=null; private Button stopIntent=null; private Intent intent1,intent2=null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_second); init(); intent1=new Intent(SecondActivity.this,MyService2.class); intent2=new Intent(SecondActivity.this,MyIntentService.class); } //按钮控件初始化 void init(){ startFore= (Button) findViewById(R.id.startFore); stopFore=(Button)findViewById(R.id.startFore); startIntent=(Button) findViewById(R.id.startIntent); stopIntent=(Button) findViewById(R.id.stopIntent); startFore.setOnClickListener(new btnListener()); stopFore.setOnClickListener(new btnListener()); startIntent.setOnClickListener(new btnListener()); stopIntent.setOnClickListener(new btnListener()); } class btnListener implements View.OnClickListener{ @Override public void onClick(View v) { switch(v.getId()){ case R.id.startFore: startService(intent1); break; case R.id.stopFore: break; case R.id.startIntent: startService(intent2); break; case R.id.stopIntent: stopService(intent2); break; default:break; } } } }
package com.example.wkp.service; import android.app.Notification; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.support.annotation.Nullable; import android.widget.RemoteViews; /** * Created by wkp on 2016/9/24. */ public class MyService2 extends Service{ @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); //创建通知实例 Notification notification=new Notification(); //图标 notification.icon=R.drawable.books; //内容 notification.contentView=new RemoteViews(getPackageName(),R.layout.notify); //跳转 notification.contentIntent= PendingIntent.getActivity(this,0,new Intent(this,SecondActivity.class),0); //开启 startForeground(1,notification); } }
package com.example.wkp.service; import android.app.IntentService; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.support.annotation.Nullable; import android.util.Log; /** * Created by wkp on 2016/9/24. */ public class MyIntentService extends IntentService{ /** * Creates an IntentService. Invoked by your subclass's constructor. * * @param name Used to name the worker thread, important only for debugging. */ public MyIntentService(String name) { super(name); } //必须创建一个无参的构造方法 public MyIntentService(){ super("MyIntentService"); } //开启一个新的线程,可以进行耗时操作 @Override protected void onHandleIntent(Intent intent) { Log.v("haha","onhandle"); Log.v("hehe",String.valueOf(Thread.currentThread().getId())); Log.v("hehe",String.valueOf(android.os.Process.myPid())); while(true){ try{ Thread.sleep(1000); Log.v("pp","I am in handle"); }catch(Exception e){ e.printStackTrace(); } } } @Override public void onCreate() { super.onCreate(); Log.v("haha","oncreate"); Log.v("hehe",String.valueOf(Thread.currentThread().getId())); Log.v("hehe",String.valueOf(android.os.Process.myPid())); } @Override public void onDestroy() { super.onDestroy(); Log.v("haha","ondestroy"); Log.v("hehe",String.valueOf(Thread.currentThread().getId())); Log.v("hehe",String.valueOf(android.os.Process.myPid())); } }
Service和IntentService的区别是后者开启新的线程可以进行耗时操作。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/startFore" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="startFore"/> <Button android:id="@+id/stopFore" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="stopFore"/> <Button android:id="@+id/startIntent" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="startIntent"/> <Button android:id="@+id/stopIntent" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="stopIntent"/> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:src="@drawable/books" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="前台服务"/> </LinearLayout>
最后Service和Broadcast Receiver结合做一个定点报时
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.wkp.clock"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".AlarmService"> </service> <receiver android:name=".AlarmReceiver"> <intent-filter> <action android:name="ALARM_ACTION" /> </intent-filter> </receiver> </application> </manifest>
package com.example.wkp.clock; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; public class MainActivity extends AppCompatActivity { private Button start=null; private Button stop=null; private EditText edit=null; private Intent intent = null; private AlarmService.AlarmBinder binder; private ServiceConnection connection=new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { binder=(AlarmService.AlarmBinder)service; } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); init(); } void init(){ start= (Button) findViewById(R.id.start); stop= (Button) findViewById(R.id.stop); edit=(EditText)findViewById(R.id.edit); start.setOnClickListener(new btnListener()); stop.setOnClickListener(new btnListener()); //绑定服务 intent=new Intent(this,AlarmService.class); bindService(intent,connection,BIND_AUTO_CREATE); } class btnListener implements View.OnClickListener{ @Override public void onClick(View v) { switch (v.getId()){ case R.id.start: binder.setTime(Integer.parseInt(edit.getText().toString())); startService(intent); break; case R.id.stop: binder.setState(); break; default: break; } } } }
package com.example.wkp.clock; import android.app.AlarmManager; import android.app.Notification; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.os.SystemClock; import android.support.annotation.Nullable; import android.util.Log; import android.widget.RemoteViews; /** * Created by wkp on 2016/9/24. */ public class AlarmService extends Service { private AlarmBinder binder = new AlarmBinder(); private AlarmManager manager; private Intent intent1; private PendingIntent pd; private int time; private boolean flag=true; @Nullable @Override public IBinder onBind(Intent intent) { //得到manager manager = (AlarmManager) getSystemService(ALARM_SERVICE); intent1 = new Intent(this, AlarmReceiver.class); intent1.setAction("ALARM_ACTION"); //得到PendingIntent pd = PendingIntent.getBroadcast(this, 0, intent1, 0); return binder; } @Override public void onCreate() { super.onCreate(); //创建通知实例 Notification notification = new Notification(); //图标 notification.icon = R.drawable.books; //内容 notification.contentView = new RemoteViews(getPackageName(), R.layout.notify); //跳转 notification.contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0); //开启 startForeground(1, notification); } @Override public int onStartCommand(Intent intent, int flags, int startId) { //设置闹钟 //类型,开机到现在的时间||1970.1.1到现在的时间||。。。wakeup唤醒CPU //具体时间计算,单位毫秒 //闹钟的意图 Log.v("hehe","alarm"); if(flag){ manager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+time*1000,pd); }else{ manager.cancel(pd); stopSelf(); } return super.onStartCommand(intent, flags, startId); } class AlarmBinder extends Binder { void setTime(int t){ time=t; flag=true; } void setState(){ flag=false; } } }
package com.example.wkp.clock; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; /** * Created by wkp on 2016/9/24. */ public class AlarmReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.v("hehe","receiver"); context.startService(new Intent(context,AlarmService.class)); } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.wkp.clock.MainActivity"> <EditText android:id="@+id/edit" android:layout_width="match_parent" android:layout_height="wrap_content"/> <Button android:id="@+id/start" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="启动"/> <Button android:id="@+id/stop" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="关闭"/> </LinearLayout>