安卓一行代码 服务的创建
10.3.1 创建服务
AndroidStudio是个牛逼的工具讲道理实在是太智能了,这波操作就是右键点击然后可以选择创建Service,之后两个选项
都勾着,第一个是否允许其他应用程序访问这个服务。,第二个是是否可用。
创建完之后就重写几个方法
package com.example.servicetest; import android.app.Service; import android.content.Intent; import android.os.IBinder; //四大组件都需要在AndroidManifest.xml文件中进行注册才能生效,AndroidStudio自动注册好了 public class MyService extends Service { public MyService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } public void onCreate(){ //在服务创建时进行调用 super.onCreate(); } //在服务启动的时候调用 public int onStartCommand(Intent intent,int flags,int startId) { return super.onStartCommand(intent,flags,startId); } //在服务销毁的时候调用 public void onDestroy() { super.onDestroy(); } }
这里讲道理是真不错的,androidstudio已经自动帮我们的服务,在AndroidManifest.xml文件中注册好了。
10.3.2 启动和停止服务
启动服务主要是靠Intent来实现的
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/start_service" android:text="Start Service" tools:ignore="MissingConstraints" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/stop_service" android:text="Stop Service" tools:ignore="MissingConstraints" /> </androidx.constraintlayout.widget.ConstraintLayout>
package com.example.servicetest; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button startService=(Button)findViewById(R.id.start_service); Button stopService=(Button)findViewById(R.id.stop_service); startService.setOnClickListener((View.OnClickListener) this); stopService.setOnClickListener((View.OnClickListener) this); } public void onClick(View v) { switch (v.getId()){ case R.id.start_service: Intent startIntent=new Intent(this,MyService.class); startService(startIntent); break; case R.id.stop_service: Intent stopIntent=new Intent(this,MyService.class); stopService(stopIntent); //停止服务 break; default: break; } } }
接下来有个问题就是怎么证实服务已经成功或者停止来呢,最简单的方法就是MyService几个方法中加入打印日志
package com.example.servicetest; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; //四大组件都需要在AndroidManifest.xml文件中进行注册才能生效,AndroidStudio自动注册好了 public class MyService extends Service { public MyService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } public void onCreate(){ //在服务创建时进行调用 super.onCreate(); Log.d("MyService","onCreate executed"); } //在服务启动的时候调用 public int onStartCommand(Intent intent,int flags,int startId) { Log.d("MyService","onStartCommand executed"); return super.onStartCommand(intent,flags,startId); } //在服务销毁的时候调用 public void onDestroy() { super.onDestroy(); Log.d("MyService","onDestory executed"); } }
onCreate()方法是在服务第一次创建的时候调用的,而onStartCommand()方法则在每次启动服务时都会调用。
10.3.3 活动和服务进行通信
因为活动和服务在启动之后有点毫无关系的感觉,如果活动可以指挥服务的话,就需要onBind()方法了
package com.example.servicetest; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; //四大组件都需要在AndroidManifest.xml文件中进行注册才能生效,AndroidStudio自动注册好了 public class MyService extends Service { private DownloadBinder mBinder=new DownloadBinder(); class DownloadBinder extends Binder{ public void startDownLoad() { Log.d("MyService","startDownload executed"); } public int getProgress() { Log.d("MyService","getProgress executed"); return 0; } } public MyService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. return mBinder; } public void onCreate(){ //在服务创建时进行调用 super.onCreate(); Log.d("MyService","onCreate executed"); } //在服务启动的时候调用 public int onStartCommand(Intent intent,int flags,int startId) { Log.d("MyService","onStartCommand executed"); return super.onStartCommand(intent,flags,startId); } //在服务销毁的时候调用 public void onDestroy() { super.onDestroy(); Log.d("MyService","onDestory executed"); } }
新建了一个DownloadBinder对象,继承Binder类,并创建了两个模拟方法,然后在onBinder方法中返回这个对象
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/uBind_Service" android:text="UBind_Service" tools:ignore="MissingConstraints" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/Bind_Service" android:text="Bind Service" tools:ignore="MissingConstraints" />
这两个按钮是绑定服务和取消绑定的,活动和服务进行一波绑定,绑定之后就可以调用Binder提供的方法了
package com.example.servicetest; import androidx.appcompat.app.AppCompatActivity; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.view.View; import android.widget.Button; import java.nio.BufferUnderflowException; public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private MyService.DownloadBinder downloadBinder; private ServiceConnection connection=new ServiceConnection() { @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { downloadBinder=(MyService.DownloadBinder)iBinder; downloadBinder.startDownLoad(); downloadBinder.getProgress(); } @Override public void onServiceDisconnected(ComponentName componentName) { } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button startService=(Button)findViewById(R.id.start_service); Button stopService=(Button)findViewById(R.id.stop_service); startService.setOnClickListener((View.OnClickListener) this); stopService.setOnClickListener((View.OnClickListener) this); Button bindService=(Button)findViewById(R.id.Bind_Service); Button unbindService=(Button)findViewById(R.id.uBind_Service); bindService.setOnClickListener(this); unbindService.setOnClickListener(this); } public void onClick(View v) { switch (v.getId()){ case R.id.start_service: Intent startIntent=new Intent(this,MyService.class); startService(startIntent); break; case R.id.stop_service: Intent stopIntent=new Intent(this,MyService.class); stopService(stopIntent); //停止服务 break; case R.id.Bind_Service: Intent bindIntent=new Intent(this,MyService.class); bindService(bindIntent,connection,BIND_AUTO_CREATE);//绑定服务 break; case R.id.uBind_Service: unbindService(connection); break; default: break; } } }
10.5.1 使用前台服务
和通知很像,这点是真的骚
package com.example.servicetest; import android.app.Notification; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.graphics.BitmapFactory; import android.os.Binder; import android.os.IBinder; import android.util.Log; import androidx.core.app.NotificationCompat; //四大组件都需要在AndroidManifest.xml文件中进行注册才能生效,AndroidStudio自动注册好了 public class MyService extends Service { private DownloadBinder mBinder=new DownloadBinder(); class DownloadBinder extends Binder{ public void startDownLoad() { Log.d("MyService","startDownload executed"); } public int getProgress() { Log.d("MyService","getProgress executed"); return 0; } } public MyService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. return mBinder; } public void onCreate(){ //在服务创建时进行调用 super.onCreate(); Log.d("MyService","onCreate executed"); Intent intent=new Intent(this,MainActivity.class); PendingIntent pi=PendingIntent.getActivity(this,0,intent,0); Notification notification=new NotificationCompat.Builder(this).setContentText("This is content text").setContentTitle("This is content title") .setWhen(System.currentTimeMillis()).setSmallIcon(R.mipmap.ic_launcher).setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher)).setContentIntent(pi).build(); startForeground(1,notification); } //在服务启动的时候调用 public int onStartCommand(Intent intent,int flags,int startId) { Log.d("MyService","onStartCommand executed"); return super.onStartCommand(intent,flags,startId); } //在服务销毁的时候调用 public void onDestroy() { super.onDestroy(); Log.d("MyService","onDestory executed"); } }