.先讲讲怎么使用bindService()绑定服务

 应用组件(客户端)可以调用bindService()绑定到一个service.Android系统之后调用service的onBind()方法,它返回一个用来与service交互的IBinder

  绑定是异步的.bindService()会立即返回,它不会返回IBinder给客户端.要接收IBinder,客户端必须创建一个ServiceConnection的实例并传

给bindService().ServiceConnection包含一个回调方法,系统调用这个方法来传递要返回的IBinder.

注:只有activities,services,和contentproviders可以绑定到一个service—你不能从一个broadcastreceiver绑定到service.

所以,从你的客户端绑定到一个service,你必须:

  • 1实现ServiceConnection.

    你的实现必须重写两个回调方法:

    • onServiceConnected()

      系统调用这个来传送在service的onBind()中返回的IBinder.

    • OnServiceDisconnected()

      Android系统在同service的连接意外丢失时调用这个.比如当service崩溃了或被强杀了.当客户端解除绑定时,这个方法不会被调用.

  • 2调用bindService(),传给它ServiceConnection的实现.

  • 3当系统调用你的onServiceConnected()方法时,你就可以使用接口定义的方法们开始调用service了.

  • 4要与service断开连接,调用unbindService().

      当你的客户端被销毁,它将从service解除绑定,但是你必须总是在你完成与service的交互时或当你的activity暂停于是service在不被使用时可以关闭此两种情况下解

    除绑定.(下面会讨论更多在适当的时候绑定和解除绑定的问题.

    使用这个ServiceConnection,客户端可以绑定到一个service,通过把它传给bindService().例如:

    Intentintent = new Intent(this, LocalService.class);

    bindService(intent,mConnection, Context.BIND_AUTO_CREATE);

  • 第一个bindService()的参数是一个明确指定了要绑定的service的Intent.

  • 第二个参数是ServiceConnection对象.

  • 第三个参数是一个标志,它表明绑定中的操作.它一般应是BIND_AUTO_CREATE,这样就会在service不存在时创建一个.其它可选的值是BIND_DEBUG_UNBIND和BIND_NOT_FOREGROUND,不想指定时设为0即可.。

补充事项

下面是一些关于绑定到service的重要事项:

  • 你总是需要捕获DeadObjectException异常.它会在连接被打断时抛出.这是被远程方法抛出的唯一异常.

  • 对象引用计数是跨进程的作用的.

  • 你应该在客户端的生命期内使绑定和解除绑定配对进行,例如:

    • 如果你需要在你的activity可见时与service交互,你应该在onStart()绑定并在onStop()中解除绑定.

    • 如果你想让你的activity即使在它停止时也能接收回应,那么你可以在onCreate()中绑定并在onDestroy()中解除绑定.注意这意味着你的activity需要使用在自己整

      个运行期间使用service(即使位于后台),所以如果service在另一个进程中,那么你增加了这个进程的负担而使它变得更容易被系统杀掉.

      注:你一般不应该在你的activity的onResume()和onPause()中绑定和解除绑定到service,因为这些回调方法,出现在每个生命期变化中,并且你需要使发生在这

      些变化中的处理最小化.还有,如果你应用中的多个activity绑定到同一个service,并且有一个变化发生在其中两个activity之间,service可能在当前activity解除绑

      定(pause中)和下一个绑定前(rusume中)被销毁又重建.

2.管理(多个客户端)BoundService的生命期

  当一个service的所有客户端都解除绑定,Android系统就销毁它(除非它是从onStartCommand()启动).如果你的service是一个纯boundservice,你不需管理它的生命

期—Android系统会为你管理它.。

  然而,如果你选择了实现onStartCommand()回调方法,那么你必须明确地停止service,因为service现在被认为是"开始的".在此情况下,service会一直运行,直

到service使用stopSelf()停止它自己或另外的组件调用了stopService()停止了它,不管是否有客户端绑定了它.

  另外,如果你的service已经启动并且接受绑定,那么当系统调用你的onUnbind()方法,你可以选择返回true表示你想在客户端下一次绑定到service时接受一个

对onRebind()的调用(而不是一个对onBind()的调用).onRebind()返回void,但是客户端依然会在它的onServiceConnected()回调中接收到IBinder.下图演示了这种生命其的

逻辑:

3。bindService和startService混合使用时

1.如果先bindService,再startService:

在bind的Activity退出的时候,Service会执行unBind方法而不执行onDestory方法,因为有startService方法调用过,所以Activity与Service解除绑定后会有一个与调用者没有关连的Service存在

2.如果先bindService,再startService,再调用Context.stopService

Service的onDestory方法不会立刻执行,因为有一个与Service绑定的Activity,但是在Activity退出的时候,会执行onDestory,如果要立刻执行stopService,就得先解除绑定

---------------------------

把上面的"如果先bindService,再startService"换成"如果先startService,再bindService",结果是一样的

问题:

如果在一个Activity的onCreate方法中,

bindService(serviceIntent, conn, Context.BIND_AUTO_CREATE);

再startService(serviceIntent);

退出这个Activity时,会执行onUnBind

但是再次进入这个Activity的时候,为什么不执行onBind方法了?只有在这个Service销毁后(执行onDestory),再进这个Activity才会执行onBind,还有就是当有两个客户端时,在第一个客户端startServie启动服务再bindService绑定服务,这时跳到第二个客户端里(启动时会调用onBind()),再客户端startServie启动服务再bindService绑定服务,启动时不会调用用onBind()了(因为之前客户端已经启动后没有onDestory()销毁Service,所以再客户端第二次绑定服务时,只会返回IBinder对象给onServiceConnected()),而且要注意的是当,当第一个服务启动并绑定一个服务时,再跳去第二个服务端启动并绑定这个服务时,第二个服务端再解绑时,不会调用onUnbind(),只有回到第一个客户端时,解绑这是才会调用onUnbind(),顺序反过来结果是一样的。得出一个结论是:当一个服务没被onDestory()销毁之前,只有第一个启动它的客户端能调用它的onBind()和onUnbind()。

package yy.android.service;

import org.apache.http.conn.ClientConnectionManager;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences.Editor;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class ServiceActivity extends Activity {
//    private final String TAG = "ServiceActivity";
    private Button unbind;
    public static IService iService=null;
    private Button mSkiptoClient;
    private Button mStart;
    public static EditText medit;
    private Button mBind;
    private Button mStop;
    public static ServiceConnection connection=new ServiceConnection() {
        public void onServiceDisconnected(ComponentName name) {
            Log.d("LOG","Activity ->Disconnected the LocalService");
        }
        public void onServiceConnected(ComponentName name, IBinder service) {
            // TODO Auto-generated method stub
            //获取连接的服务对象
              //System.out.println("Connection!!!");
              iService=(IService)service;
              medit.setText(iService.getName());
              Log.d("LOG","Activity ->Connected the Service");
        }
    };  
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Log.d("LOG","Activity ->OnCreate");
        unbind = (Button)findViewById(R.id.unbind);
        mSkiptoClient = (Button)findViewById(R.id.skip);
        mStart = (Button)findViewById(R.id.start);
        mStop = (Button )findViewById(R.id.stop);
        medit = (EditText)findViewById(R.id.edit);
        mBind = (Button)findViewById(R.id.connection);
        mBind.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                // TODO Auto-generated method stub
                 Intent intent=new Intent(ServiceActivity.this,LocalService.class);
                 bindService(intent,connection, BIND_AUTO_CREATE);    
            }
        });
        mStart.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent intent=new Intent(ServiceActivity.this,LocalService.class);    
                startService(intent);
            }
        });
        mStop.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent intent=new Intent(ServiceActivity.this,LocalService.class);
                stopService(intent);
            }
        });
        mSkiptoClient.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                Intent intent = new Intent("android.intent.action.YClient");
                startActivity(intent);
            }
        });
        unbind.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                // TODO Auto-generated method stub
                unbindService(connection);
            }
        });
    }
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        Log.d("LOG","Activity ->OnDestory");
    }
    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
//        unbindService(connection);
        Log.d("LOG","Activity ->OnPause");
        super.onPause();
        
    }
    @Override
    protected void onRestart() {
        // TODO Auto-generated method stub
        super.onRestart();
        Log.d("LOG","Activity ->OnRestart");
    }
    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        Log.d("LOG","Activity ->OnResume");
//         Intent intent=new Intent(ServiceActivity.this,LocalService.class);
//         bindService(intent,connection, BIND_AUTO_CREATE);    
        super.onResume();
        
    }
    protected void onStart() {
        // TODO Auto-generated method stub
        super.onStart();
        Log.d("LOG","Activity ->OnSatrt");
    }
    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();
        Log.d("LOG","Activity ->OnStop");
    }

}

////////////////////////////////////////////////////////////////////////////

package yy.android.service;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class CLient extends Activity{
    private IService iService2=null;
    private Button unbind2;
    private Button mStart2;
    private EditText medit2;
    private Button mBind2;
    private Button mStop2;
    ServiceConnection connection2=new ServiceConnection() {
         public void onServiceDisconnected(ComponentName name) {
            Log.d("LOG","Client ->Disconnected the LocalService");
        }
        public void onServiceConnected(ComponentName name, IBinder service) {
            // TODO Auto-generated method stub
             //获取连接的服务对象
              //System.out.println("Connection!!!");
              iService2=(IService)service;
               medit2.setText(iService2.getName());
               Log.d("LOG","Client ->Connected the Service");
        }
     };  
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.client);
        Log.d("LOG","Client ->OnCreate");
        unbind2 = (Button)findViewById(R.id.unbind2);
        mStart2 = (Button)findViewById(R.id.start2);
        mStop2 = (Button )findViewById(R.id.stop2);
        medit2 = (EditText)findViewById(R.id.edit2);
        mBind2 = (Button)findViewById(R.id.connection2);
        mBind2.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                // TODO Auto-generated method stub
                 Intent intent=new Intent(CLient.this,LocalService.class);
                 bindService(intent,connection2, BIND_AUTO_CREATE);    
            }    
        });    
        mStart2.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {  
                // TODO Auto-generated method stub
                Intent intent=new Intent(CLient.this,LocalService.class);    
                startService(intent);
            }
        });
        mStop2.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent intent=new Intent(CLient.this,LocalService.class);
                stopService(intent);
            }
        });
        unbind2.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Log.e("LOG", "Unbind");
                unbindService(connection2);
                Log.e("LOG", "Unbind");
            }  
        });
    }     
    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        //unbindService(connection2);
        Log.d("LOG","Client ->OnDestory");
        super.onDestroy();
        
    }
    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        Log.d("LOG","Client ->OnPause");
    }
    @Override
    protected void onRestart() {
        // TODO Auto-generated method stub
        super.onRestart();
        Log.d("LOG","Client ->OnRestart");
    }
    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        Log.d("LOG","Client ->OnResume");
    }
    @Override
    protected void onStart() {
        // TODO Auto-generated method stub
        super.onStart();
        Log.d("LOG","Client ->OnSatrt");
    }
    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();
        Log.d("LOG","Client ->OnStop");
    }
    
}
///////////////////////////////////////////////////////////////////

package yy.android.service;
 
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class LocalService extends Service{
    private MyBind myBind=new MyBind();
    
    public IBinder onBind(Intent intent) {
            //System.out.println("Service onBind!!!");
            Log.d("LOG","LocalService ->onBind");
            return myBind;
        }
    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        Log.d("LOG","LocalService ->onCreate");
        super.onCreate();
        
    }
     @Override
    public void onDestroy() {
        // TODO Auto-generated method stub
         Log.d("LOG","LocalService ->onDestory");
        super.onDestroy();
        
    }
    @Override
    public void onStart(Intent intent, int startId) {
        // TODO Auto-generated method stub
        Log.d("LOG","LocalService ->onSatrt");
        super.onStart(intent, startId);
        
    }
    @Override  
    public boolean onUnbind(Intent intent) {
        // TODO Auto-generated method stub
        Log.d("LOG","LocalService ->onUnbind");
        return super.onUnbind(intent);
        //return true;
    }
    
    @Override
    public void onRebind(Intent intent) {
        // TODO Auto-generated method stub
        Log.d("LOG","LocalService ->onRebind");
        super.onRebind(intent);
        
    }

public class MyBind extends Binder implements IService{

public String getName() {
             // TODO Auto-generated method stub
             return "YUZHIBOYI";
         }
     }
}
/////////////////////////////////////////////////////////////////////////

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="yy.android.service"
    android:versionCode="1"
    android:versionName="1.0" >

<uses-sdk android:minSdkVersion="10" />

<application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".ServiceActivity"
            
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".CLient"
            
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.YClient" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <service android:name=".LocalService">
           <intent-filter>  
               <action android:name="com.yy.yy"/>
               <category android:name="android.intent.category.DEFAULT" />
           </intent-filter>  
        </service>   
    </application>
</manifest>

/////////////////////////////////////////////////////////

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <EditText
        android:id="@+id/edit2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
    ></EditText>     
    <Button  
        android:id = "@+id/connection2"  
        android:layout_width = "wrap_content"  
        android:layout_height = "wrap_content"  
        android:text = "@string/Bind"  
        />  
        <Button  
        android:id = "@+id/start2"  
        android:layout_width = "wrap_content"  
        android:layout_height = "wrap_content"  
        android:text = "@string/Start"  
        />  
        <Button  
        android:id = "@+id/stop2"  
        android:layout_width = "wrap_content"  
        android:layout_height = "wrap_content"  
        android:text = "@string/StopService"  
        />  
          <Button  
        android:id = "@+id/unbind2"  
        android:layout_width = "wrap_content"  
        android:layout_height = "wrap_content"  
        android:text = "@string/UnbindService"  
        />
</LinearLayout>

//////////////////////////////////////////////////////

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
   <EditText
        android:id="@+id/edit"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
    ></EditText>     
    <Button  
        android:id = "@+id/connection"  
        android:layout_width = "wrap_content"  
        android:layout_height = "wrap_content"  
        android:text = "@string/Bind"  
        />  
        <Button  
        android:id = "@+id/start"  
        android:layout_width = "wrap_content"  
        android:layout_height = "wrap_content"  
        android:text = "@string/Start"  
        />  
        <Button  
        android:id = "@+id/stop"  
        android:layout_width = "wrap_content"  
        android:layout_height = "wrap_content"  
        android:text = "@string/StopService"  
        />  
        <Button  
        android:id = "@+id/skip"  
        android:layout_width = "wrap_content"  
        android:layout_height = "wrap_content"  
        android:text = "@string/Skip"  
        />  
        <Button  
        android:id = "@+id/unbind"  
        android:layout_width = "wrap_content"  
        android:layout_height = "wrap_content"  
        android:text = "@string/UnbindService"  
        /> 
</LinearLayout>

////////////////////////////////////////////////////

混合使用的时候总结的,欢迎大家来一起讨论!

【Android 界面效果34】Android里Service的bindService()和startService()混合使用深入分析的更多相关文章

  1. 【Android 界面效果25】android中include标签的使用

    在一个项目中我们可能会需要用到相同的布局设计,如果都写在一个xml文件中,代码显得很冗余,并且可读性也很差,所以我们可以把相同布局的代码单独写成一个模块,然后用到的时候可以通过<include ...

  2. 【Android 界面效果21】Android ViewPager使用详解

    这是谷歌官方给我们提供的一个兼容低版本安卓设备的软件包,里面包囊了只有在安卓3.0以上可以使用的api.而viewpager就是其中之一利用它,我们可以做很多事情,从最简单的导航,到页面菜单等等.那如 ...

  3. 【Android 界面效果17】Android手机平板两不误,使用Fragment实现兼容手机和平板的程序

    记得我之前参与开发过一个华为的项目,要求程序可以支持好几种终端设备,其中就包括Android手机和Android Pad.然后为了节省人力,公司无节操地让Android手机和Android Pad都由 ...

  4. 【Android 界面效果31】Android--侧滑菜单应用的实现

    侧滑菜单应用现在非常多,而且实现方式也多种多样.通过在网上的多方查找,我找到郭霖少侠的这篇文章:http://blog.csdn.net/guolin_blog/article/details/874 ...

  5. 【Android 界面效果23】LayoutInflater作用及使用

    作用:  1.对于一个没有被载入或者想要动态载入的界面, 都需要使用inflate来载入. 2.对于一个已经载入的Activity, 就可以使用实现了这个Activiyt的的findViewById方 ...

  6. 【Android 界面效果22】Android的Tab与TabHost

    Tab与TabHost 这就是Tab,而盛放Tab的容器就是TabHost 如何实现?? 每一个Tab还对应了一个布局,这个就有点好玩了.一个Activity,对应了多个功能布局. ①新建一个Tab项 ...

  7. 【Android 界面效果18】Android软件开发之常用系统控件界面整理

    [java] view plaincopyprint?   <span style="font-size:18px">1.文本框TextView TextView的作用 ...

  8. 【Android 界面效果16】关于android四大组件的总结

    Android四大组件:Activity.Service.Broadcast receiver.Content provider 在Android中,一个应用程序可以使用其它应用程序的组件,这是And ...

  9. 【Android 界面效果13】关于全屏和取消标题栏

    ------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 去掉标题栏: 第一种:也一般入门的时候经常使用的一种方法 requestWindowFeature(Wi ...

随机推荐

  1. 找回使用过的QQ头像

    多么渴望那双眼睛能在万紫千红中发现自己:然而眼睛从来就不曾对自己留意:于是换种落寞再次接受垂直打击:然后然后的然后尼玛再换个逗比的头像证明老资无所谓老资无所谓嘿嘿: 我们换头像的时候,发现之前的一个最 ...

  2. zendstudio 出现failed to create the java machine转

    是因为配置java虚拟机内存太小 打开zend for eclipse 10.5时报了个错: failed to create the java virtual machine google了一下,解 ...

  3. hdoj 5375 Gray Code

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5375 编码规则:tmp = XOR(gr[i],gr[i-1]); 算是找规律的题目吧,考虑?前后字符 ...

  4. 如何加入自定义WebControl

    http://www.screencast.com/users/Dennis.Garavsky/folders/Default/media/c75b4ec6-1641-4f82-936e-39360d ...

  5. CSS Layout

    fontline-heightcolormarginpaddingbordertext-alignbackground widthheightfloatcleardisplay 定位属性 属 性 描 ...

  6. 组件化CSS--管理你整站的CSS文件

    为什么要拆分样式文件? 更易于查找样式规则. 简化维护,方便管理. 还可以针对某一页面提供特定的样式. 为什么要添加桥接样式? 你可以随时添加或移除样式而不需要修改HTML 文档. 为什么要定义两种媒 ...

  7. [每日一题] OCP1z0-047 :2013-08-06 外表部――相关描述

    这道题目的知识点是要你熟悉外部表,怎么建外部表,外部表的数据是怎么存储的等等.请给出正确答案,并解释A B C D每项,最好用实验测试证明! 外部表的metadata(元数据)是存在数据库中,但它的数 ...

  8. [Angular2 Router] CanActivate Route Guard - An Example of An Asynchronous Route Guard

    In this tutorial we are going to learn how we can to configure an can activate route guard in the An ...

  9. RotateAnimation详解

    其他构造器的旋转也可参考这副图. RotateAnimation旋转坐标系为以旋转点为坐标系(0,0)点.x轴为0度,顺时针方向旋转一定的角度.        1.RotateAnimation(fr ...

  10. 利用URLScan工具过滤URL中的特殊字符(仅针对IIS6)

    客户公司搞安全检查,扫描出来我们之前做的系统有一个高危漏洞:IIS tilde directory enumeration,也就是利用“~”字符猜解暴露短文件/文件夹名,比如,采用这种方式构造URL: ...