为什么用 unbindService() 方法解绑定服务后 仍然可以调用服务中的方法

rtcw2001 2016-07-03 09:35:09
为什么我用 unbindService 方法解除了绑定后,仍然可以在 活动中调用 服务中的方法,解除绑定后,服务确实已经调用了 onDestory方法销毁了服务,为什么还能调用服务中的方法呢?


活动的代码:

package com.example.myservicetest;

import com.example.myservicetest.MyService.*;

import android.app.*;
import android.content.*;
import android.view.*;
import android.view.View.*;
import android.os.*;
import android.util.Log;
import android.widget.*;

public class MainActivity extends Activity implements OnClickListener {

//--------------------------------------------------------------------
private Button b1, b2, b3, b4, b5;
private ServiceConnection connection;
private MyService myService;
private Intent in;

//--------------------------------------------------------------------
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//获取按钮
b1 = (Button)findViewById(R.id.bind);
b2 = (Button)findViewById(R.id.unbind);
b3 = (Button)findViewById(R.id.play);
b4 = (Button)findViewById(R.id.start);
b5 = (Button)findViewById(R.id.stop);

//注册点击事件
b1.setOnClickListener(this);
b2.setOnClickListener(this);
b3.setOnClickListener(this);
b4.setOnClickListener(this);
b5.setOnClickListener(this);

//用于连接服务
connection = new ServiceConnection()
{
@Override
public void onServiceDisconnected(ComponentName name)
{
Log.e("connection", "连接意外丢失");
}

@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
myService = ((MyBinder)service).getMyService();
Log.e("connection", "连接完成");
}
};

//启动服务意图
in = new Intent(this, MyService.class);

}

//--------------------------------------------------------------------
@Override
public void onClick(View v)
{
switch(v.getId())
{
//启动服务
case R.id.start:
startService(in);
break;

//停止服务
case R.id.stop:
stopService(in);
break;

//绑定服务
case R.id.bind:
bindService(new Intent(this, MyService.class), connection, BIND_AUTO_CREATE);
break;

//解绑服务
case R.id.unbind:
unbindService(connection);
break;

//调用服务中的方法
case R.id.play:
myService.play();
break;
}
}

}


服务的代码:

package com.example.myservicetest;

import android.app.*;
import android.content.*;
import android.os.*;
import android.util.Log;

public class MyService extends Service {

private MyBinder mBinder;

public class MyBinder extends Binder {
public MyService getMyService()
{
return MyService.this;
}
}

//--------------------------------------------------------------------
@Override
public void onCreate()
{
super.onCreate();
mBinder = new MyBinder();
Log.e("Service", "创建服务");
}

//--------------------------------------------------------------------
@Override
public IBinder onBind(Intent intent)
{
Log.e("Service", "执行onBind");
return mBinder;
}

//--------------------------------------------------------------------
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.e("Service", "执行onStartCommand");
return START_NOT_STICKY;
}

//--------------------------------------------------------------------
@Override
public boolean onUnbind(Intent intent)
{
Log.e("Service", "执行onUnbind");
return false;
}

//--------------------------------------------------------------------
@Override
public void onDestroy()
{
Log.e("Service", "服务销毁");
super.onDestroy();
}




//--------------------------------------------------------------------
public void play()
{
Log.e("binder", "播放音乐");
}

}




执行结果:
启动服务-绑定服务-播放-播放-解绑服务-停止服务-播放-播放
...全文
1637 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
徐乙 2018-03-20
  • 打赏
  • 举报
回复 1
这是内存泄漏了,你仍然维持着service的强引用,gc roots通过你的活动依然可以抵达服务。虽然service的销毁周期都跑了,onDestory试图去销毁服务,但是无法做到这一点。这个时候,这已经不是一个服务了,就是一个普通的类,你就是简单的在调用这个类的方法。 //////////// 你要把类和组件区分开。你这个问题就好比与new了一个碎片,就认为他已经初始化了,当然不是。。。只有通过事务与消息机制,进行处理,你的碎片才得到真正意义上的实例化。
bs243458584 2017-06-11
  • 打赏
  • 举报
回复
引用 8 楼 kokoromiro 的回复:
[quote=引用 6 楼 heaimnmn 的回复:] play方法在,不代表service在运行,只是说明这个类没有被回收
. 那bindService这个方法的作用是什么呢, 到底应该怎么用? 我一直都觉得是这么用,但现在看来应该不是这么用了.[/quote] service里的play方法就不该是public,用onStartCommand方法调用play才对。不要直接去持有service对象调用内部方法,要用onBind方法返回给onServiceConnection方法的IBind对象来实现与service的通信。
潇潇独行侠 2016-11-09
  • 打赏
  • 举报
回复
楼主解决没,可否告知,鄙人也是这点疑惑~
开发者_android 2016-07-04
  • 打赏
  • 举报
回复
引用 3 楼 kokoromiro 的回复:
[quote=引用 2 楼 dalor 的回复:] 如上所说。你直接创建了myService对象,调用它的play方法,你的对象在,能调用它的方法,这是最正常不过的。
也就是说,即便解除绑定,服务调用过了destroy方法,服务对象依然存在呗,那正常的用法是怎么用的?[/quote] 你还是要看看service的详细说明和使用。 销毁service,并不是把service对象设置为null.
哎,真难 2016-07-04
  • 打赏
  • 举报
回复
play方法在,不代表service在运行,只是说明这个类没有被回收
xing880307 2016-07-04
  • 打赏
  • 举报
回复
在service的onstart中调用自己的play方法。播放调用startservice(),停止播放调用stopservice
rtcw2001 2016-07-04
  • 打赏
  • 举报
回复
引用 1 楼 liudashao0 的回复:
你这是通过bindservice调用服务里面的方法? 你继承 Binder然后getMyService()里面返回的是这个类,你就根本没有通过bindservice调用服务里面的方法,你就直接调用了play方法,
不经过绑定就无法获得服务对象啊,也就没法调用服务的方法,怎么叫直接调用呢? 难道不是通过绑定来获得服务对象从而执行服务的方法吗? 那正常应该怎么用?
rtcw2001 2016-07-04
  • 打赏
  • 举报
回复
引用 2 楼 dalor 的回复:
如上所说。你直接创建了myService对象,调用它的play方法,你的对象在,能调用它的方法,这是最正常不过的。
也就是说,即便解除绑定,服务调用过了destroy方法,服务对象依然存在呗,那正常的用法是怎么用的?
开发者_android 2016-07-04
  • 打赏
  • 举报
回复
如上所说。你直接创建了myService对象,调用它的play方法,你的对象在,能调用它的方法,这是最正常不过的。
rtcw2001 2016-07-04
  • 打赏
  • 举报
回复
引用 6 楼 heaimnmn 的回复:
play方法在,不代表service在运行,只是说明这个类没有被回收
. 那bindService这个方法的作用是什么呢, 到底应该怎么用? 我一直都觉得是这么用,但现在看来应该不是这么用了.
liudashao0 2016-07-03
  • 打赏
  • 举报
回复
你这是通过bindservice调用服务里面的方法? 你继承 Binder然后getMyService()里面返回的是这个类,你就根本没有通过bindservice调用服务里面的方法,你就直接调用了play方法,
源码地址: https://pan.quark.cn/s/b198768e5234 在Android应用开发领域,服务Service)是一种用于执行持续性操作的组件,它不包含用户界面,但能够与其他组件(例如Activity)进行交互。 本文将详细研究如何运用`bindService`和`unbindService`方法服务进行交互,这是服务生命周期管理的关键环节。 一、Service的基础概念Service是Android四大组件之一,它能够在后台持续运行,即便用户退出应用程序,服务依旧可以继续执行。 服务通常用于处理如播放音乐、定时执行任务、进行网络通信等需要较长时间运行的操作。 二、bindService`bindService`方法是建立与已运行服务的连接的核心。 该方法需要三个参数:1. `Intent`:用于描述将要启动的服务,其包含了服务的类名或特定的ACTION。 2. `ServiceConnection`:一个接口,其实现定义了连接成功或失败时的回调函数,如`onServiceConnected`(表示连接成功)和`onServiceDisconnected`(表示连接断)。 3. `flags`:一个可选参数,用于设定绑定服务的一些额外选项,比如`BIND_AUTO_CREATE`(如果服务不存在,则自动创建服务)。 当调用`bindService`时,系统会尝试定位并启动指定的服务。 若服务已经运行,系统将直接建立连接。 一旦连接建立成功,`onServiceConnected`将被触发,此时可以通过返回的`IBinder`对象与服务进行通信。 三、ServiceConnection的深入分析`ServiceConnection`接口提供了与服务交...

80,491

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧