任务描述:在MyService里提供一个下载功能,然后再Activity中可以决定何时开始下载,以及随时查看下载进度。
按照之前的思路:在MyService中创建一个方法,用以对下载进行管理。然后在MainActivity中调用该方法。
1.修改布局如下:
添加了一个控制下载的按钮。
2.在MyService中添加管理下载的方法
public void startDownload(){ Toast.makeText(this,"开始下载",Toast.LENGTH_LONG).show(); }
3.在MainActivity中调用该方法
public void startDownload(View view) { MyService myService = new MyService(); myService.startDownload(); }
现在运行看看效果:
毫不意外的,崩掉了。
原因是空指针异常。
Toast.makeText(this,"开始下载",Toast.LENGTH_LONG).show();
this这里的上下文空指针异常。
不能通过该形式实现,换一个思路,借助前一篇中我们忽略的onBind()方法便可。如下:
实现思路:在MyService里创建一个专门的Binder对象来对下载进行管理。(通过绑定的形式来启动服务)
修改MyService的代码,修改后如下:
public class MyService extends Service { private static final String TAG = "MyService";
//新建DownloadBinder类,并让它继承Binder,任何在其内部提供开始下载的方法。 public class DownloadBinder extends Binder{ public void startDownload(){ Log.d("MyService","开始下载"); Toast.makeText(getApplicationContext(),"开始下载",Toast.LENGTH_LONG).show(); } } @Override public IBinder onBind(Intent intent) { return new DownloadBinder(); //将返回值修改为创建一个DownloadBinder的对象 } @Override public void onCreate() { super.onCreate(); Log.d(TAG,"onCreate"); } @Override public void onDestroy() { super.onDestroy(); Log.d(TAG,"onDestroy"); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG,"onStartCommand"); return super.onStartCommand(intent, flags, startId); } }
修改MainActivity的代码,修改后如下:
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; public MyService.DownloadBinder downloadBinder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main2); } //开启服务 public void startService(View view) { Intent intent = new Intent(); intent.setClass(this, MyService.class); startService(intent); } //结束服务 public void stopService(View view) { Intent intent = new Intent(); intent.setClass(this, MyService.class); stopService(intent); } private ServiceConnection serviceConnection = new ServiceConnection() { //创建一个ServiceConnection的内部类,并重写里面的方法。 @Override public void onServiceConnected(ComponentName name, IBinder service) { //该方法会在Activity和Service绑定成功的时候调用。 Log.d(TAG,"onServiceConnected"); downloadBinder =(MyService.DownloadBinder) service; //通过向下转型得到了DownloadBinder的实列 downloadBinder.startDownload(); } @Override public void onServiceDisconnected(ComponentName name) { //该方法只有在Service的创建崩溃或者被杀掉的时候才会调用,并不常用。 } }; //开始下载 public void startDownload(View view) { Intent intent = new Intent(); intent.setClass(this,MyService.class); bindService(intent,serviceConnection, BIND_AUTO_CREATE);//绑定服务
//第一个参数是Intent对象,第二个参数是前面创建出来的ServiceConnection实例,
//第三个参数是一个标志位,这里的BIND_AUTO_CREATE表示在Activity和Service绑定后自动创建Service.
} }
现在来运行一下:
可以看到,以及运行成功了。
任何一个Service在整个应用程序范围内都是通用的。即MyService不仅可以和MainActivty绑定,还可以和任何一个其他的Activity进行绑定,并且在绑定完成后,它们都可以获取相同的DownloadBinder实例。
标签:Service,void,MyService,intent,Activity,Intent,Android,public From: https://www.cnblogs.com/Xiang-MY/p/16603224.html