初学安卓踩过的坑和心得体会(二)——Service
2018-01-07 15:53
162 查看
今天整理的是安卓四大基本组件中的第二个组件——service
首先和前面一样,新建工程,在和mainActivity同级目录下新建一个EcohService的java文件,我是为了好记,名字不重要,自己可以随便起。新建之后我们将它在manifests.xml中进行注册。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.koogllz.myservices"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" 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=".EcohServices"></service> </application> </manifest>如倒数第三行
接下来在activity_main.xml中新建两个按钮,直接在design界面拖拽两个按钮即可
<Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="start" /> <Button android:id="@+id/button2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="stop" />接下来在mainActivity中进行声明和绑定id
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnStart=findViewById(R.id.button); btnStop=findViewById(R.id.button2); i=new Intent(this, EcohServices.class); btnStart.setOnClickListener(this); btnStop.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.button: startService(i); break; case R.id.button2: stopService(i); break; } } }其中的this是因为想使用同一个监听器事件,能够读取当前service的状态,能够继续操作,所以将本类作为onclickListener的实现类,下面的onClick方法是重写方法。
intent是作为其中传递的对象而存在。
下面做一个分支,如果点击到了button就执行开始,点击到了button2就执行结束。
回到ecohServices.java中,将其继承services,并且写入onCreate和onDestroy方法
public class EcohServices extends Service { @Nullable @Override public IBinder onBind(Intent intent) {//继承Service后不要忘记重写此方法 return null; } @Override public void onCreate() { System.out.println("create"); super.onCreate(); } @Override public void onDestroy() { System.out.println("destroy"); super.onDestroy(); } }接下来就可以在虚拟机中运行了,我们可以发现在点击button1时会出现create字样,点击button2会出现destroy字样,证明我们绑定成功了。
接下来就是在Service中进行通信,需要用到Service绑定。
我们在activity_main.xml中新建两个按钮“绑定”和“解绑”(这里不再赘述代码)并且在两个按钮上增加this监听器,在下面的onclick事件分支上新建这两个按钮按下后的操作。
public class MainActivity extends Activity implements View.OnClickListener, ServiceConnection { private Button btnStart,btnStop,bund,unbund; private Intent i; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnStart=findViewById(R.id.button); btnStop=findViewById(R.id.button2); bund=findViewById(R.id.bund); unbund=findViewById(R.id.unbund); i=new Intent(this, EcohServices.class); btnStart.setOnClickListener(this); btnStop.setOnClickListener(this); bund.setOnClickListener(this); unbund.setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.button: startService(i); break; case R.id.button2: stopService(i); break; case R.id.bund: bindService(i,this, Context.BIND_AUTO_CREATE);//这里的this是servicConnection类型所以要将本类实现serviceConnection接口。 break; case R.id.unbund: unbindService(this); break; } } @Override//实现serviceConnection接口后的两个方法 public void onServiceConnected(ComponentName componentName, IBinder iBinder) { System.out.println("onservices successful!"); } @Override public void onServiceDisconnected(ComponentName componentName) { //崩溃才会用到 } }
接着我们回到EcohService.java中将onbind方法中打印一个“onbind”字符串,来检验方法执行效果。
运行程序后我们可以看到点击bund按钮他会先create一个Service之后才会执行onbind绑定方法,但是onserviceConnected方法并没有被执行。原因是我们在onbind方法中的返回值null,没有做更改。
此时我们查看onbind方法的但回执是IBinder,我们到api文档中找到了一个系统给的基本的实现类binder,我们在下面写一个内部类,扩展自binder,然后我们将我们的返回值变成这个类的对象即可。
public IBinder onBind(Intent intent) { System.out.println("onbind"); return serviceBinder; } public final SeBinder serviceBinder=new SeBinder(); public class SeBinder extends Binder{ }
我们继续进行调试,发现我们create一个程序之后在点击绑定按钮,他不会再重新create一遍,而进行stop销毁service之后我们直接点击绑定按钮,它会先create一个然后再绑定,输出“onbind”和“serviceConnectied successful!”也就是说在系统中我们cerate一个新的service只会有一个实例化存在。如果要销毁一个程序要同时执行解绑和stop方法才会成功销毁。
如果通过create启动的service在销毁当前activity的时候(比如按后退键)服务是不会停止的,但是如果是通过bind启动的service,在销毁当前activity的时候服务也会被销毁。
接下来我们看一下数据的传递
我们在下面新建两个变量一个是timer,一个是task;
private Timer timer=null; private TimerTask task=null; private int i=0; public void startTimer(){//新建一个开始计时方法 if (timer==null){ timer=new Timer(); task=new TimerTask() { @Override public void run() {//实现timerTask的方法 i++; System.out.println(i);//让计时器加一 } }; timer.schedule(task,1000,1000);每隔一秒加一秒 } } public void stopTimer(){//新建一个停止计时方法 if(timer!=null){ timer.cancel(); task.cancel(); timer=null; task=null; } }我们在新建的内部类中创建一个getservice()方法,返回本类当前状态,然后再写一个getCurrentNum()方法能够获得当前状态值。
public IBinder onBind(Intent intent) { System.out.println("onbind"); return serviceBinder; } public final SeBinder serviceBinder=new SeBinder(); public class SeBinder extends Binder{ public EcohServices getservices(){ return EcohServices.this; } } public int getCurrentNum(){ return i; }
接下来我们回到mainactivity类中获取这个EcohServices
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {//此处自动生成的iBinder System.out.println("onservices successful!"); ecohServices= ((EcohServices.SeBinder)iBinder).getservices(); }
接下来我们新建一个获取这个值的按钮getnum,方法不再赘述,然后我们在分支判断的时候如果点击了这个按钮我们判断一下ecohservice是否为空,如果他获得了值就证明我们获得了值,成功了所以代码:
case R.id.unbund: unbindService(this); ecohServices=null; break; case R.id.getnum: if(ecohServices!=null){ System.out.println("当前值"+ecohServices.getCurrentNum()); }我们输出获取的值,但是上面的在销毁和解绑的时候我们要记得将值置回null,不然一直是非空就会出现问题。
总结
我们不能自己新建service,只能通过onCreate和onDestroy方法申请系统为我们创建。在多个按钮分享同一个状态的时候我们可以使用本类作为监视对象,在onclick方法中进行分支比较,做出相应的反应,也可以大大提升效率。
传递值和传递对象的逻辑要自己掌握清楚
写了一个判断条件要想一想什么时候应出现相反的条件约束,以便程序能够正常循环。
进行某种带有新的接口类型的时候可以使用本类实现接口即可。
相关文章推荐
- 初学安卓的踩过的坑和心得体会(一)——Activity
- 初学安卓的踩过的坑和心得体会(三)——Broadcast Receiver
- Python初学心得体会
- 初学函数心得体会
- 初学Git的一些心得体会
- 安卓开发学习心得-------欢迎界面的心得体会
- 关于安卓实训(打飞机游戏)的心得体会
- 安卓开发的心得体会
- 初学Hibernate心得体会
- (一)Croda 初学 心得 体会
- PHP框架Laravel学习心得体会
- 学习面相对象编程心得体会
- 一篇好文: VHDL 编程的一些心得体会
- 初学二维数组心得
- 使用 mac 最近一段时间获得的一些心得体会
- 魔兽争霸war3心得体会(二):狗转蜘蛛,DK光环+游侠二发
- 项目管理心得:一个项目经理的个人体会、经验总结
- 安卓开发让service自启动
- flex开发心得体会经验
- 第一次项目发布的心得体会