精华内容
下载资源
问答
  • android service

    千次阅读 2014-05-09 00:31:32
    相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Android程序员如果连Service都没听说过的话,那确实也太逊了。Service作为Android四大组件之一,在每一个应用程序中都扮演着非常重要的角色。它主要...

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435

    相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Android程序员如果连Service都没听说过的话,那确实也太逊了。Service作为Android四大组件之一,在每一个应用程序中都扮演着非常重要的角色。它主要用于在后台处理一些耗时的逻辑,或者去执行某些需要长期运行的任务。必要的时候我们甚至可以在程序退出的情况下,让Service在后台继续保持运行状态。

    不过,虽然Service几乎被每一个Android程序员所熟知,但并不是每个人都已经将Service的各个知识点都掌握得非常透彻。那么今天我就将带着大家对Service进行一次全面、深入的探究,希望每个人在读完本篇文章后都能对Service有更深一层的理解。

    Service的基本用法

    关于Service最基本的用法自然就是如何启动一个Service了,启动Service的方法和启动Activity很类似,都需要借助Intent来实现,下面我们就通过一个具体的例子来看一下。

    新建一个Android项目,项目名就叫ServiceTest,这里我选择使用4.0的API。

    然后新建一个MyService继承自Service,并重写父类的onCreate()、onStartCommand()和onDestroy()方法,如下所示:

    [java]  view plain copy
    1. public class MyService extends Service {  
    2.   
    3.     public static final String TAG = "MyService";  
    4.   
    5.     @Override  
    6.     public void onCreate() {  
    7.         super.onCreate();  
    8.         Log.d(TAG, "onCreate() executed");  
    9.     }  
    10.   
    11.     @Override  
    12.     public int onStartCommand(Intent intent, int flags, int startId) {  
    13.         Log.d(TAG, "onStartCommand() executed");  
    14.         return super.onStartCommand(intent, flags, startId);  
    15.     }  
    16.       
    17.     @Override  
    18.     public void onDestroy() {  
    19.         super.onDestroy();  
    20.         Log.d(TAG, "onDestroy() executed");  
    21.     }  
    22.   
    23.     @Override  
    24.     public IBinder onBind(Intent intent) {  
    25.         return null;  
    26.     }  
    27.   
    28. }  
    可以看到,我们只是在onCreate()、onStartCommand()和onDestroy()方法中分别打印了一句话,并没有进行其它任何的操作。

    然后打开或新建activity_main.xml作为程序的主布局文件,代码如下所示:

    [html]  view plain copy
    1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     android:layout_width="match_parent"  
    3.     android:layout_height="match_parent"  
    4.     android:orientation="vertical" >  
    5.   
    6.     <Button  
    7.         android:id="@+id/start_service"  
    8.         android:layout_width="match_parent"  
    9.         android:layout_height="wrap_content"  
    10.         android:text="Start Service" />  
    11.   
    12.     <Button  
    13.         android:id="@+id/stop_service"  
    14.         android:layout_width="match_parent"  
    15.         android:layout_height="wrap_content"  
    16.         android:text="Stop Service" />  
    17.   
    18. </LinearLayout>  
    我们在布局文件中加入了两个按钮,一个用于启动Service,一个用于停止Service。

    然后打开或新建MainActivity作为程序的主Activity,在里面加入启动Service和停止Service的逻辑,代码如下所示:

    [java]  view plain copy
    1. public class MainActivity extends Activity implements OnClickListener {  
    2.   
    3.     private Button startService;  
    4.   
    5.     private Button stopService;  
    6.   
    7.     @Override  
    8.     protected void onCreate(Bundle savedInstanceState) {  
    9.         super.onCreate(savedInstanceState);  
    10.         setContentView(R.layout.activity_main);  
    11.         startService = (Button) findViewById(R.id.start_service);  
    12.         stopService = (Button) findViewById(R.id.stop_service);  
    13.         startService.setOnClickListener(this);  
    14.         stopService.setOnClickListener(this);  
    15.     }  
    16.   
    17.     @Override  
    18.     public void onClick(View v) {  
    19.         switch (v.getId()) {  
    20.         case R.id.start_service:  
    21.             Intent startIntent = new Intent(this, MyService.class);  
    22.             startService(startIntent);  
    23.             break;  
    24.         case R.id.stop_service:  
    25.             Intent stopIntent = new Intent(this, MyService.class);  
    26.             stopService(stopIntent);  
    27.             break;  
    28.         default:  
    29.             break;  
    30.         }  
    31.     }  
    32.   
    33. }  
    可以看到,在Start Service按钮的点击事件里,我们构建出了一个Intent对象,并调用startService()方法来启动MyService。然后在Stop Serivce按钮的点击事件里,我们同样构建出了一个Intent对象,并调用stopService()方法来停止MyService。代码的逻辑非常简单,相信不需要我再多做解释了吧。

    另外需要注意,项目中的每一个Service都必须在AndroidManifest.xml中注册才行,所以还需要编辑AndroidManifest.xml文件,代码如下所示:

    [html]  view plain copy
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     package="com.example.servicetest"  
    4.     android:versionCode="1"  
    5.     android:versionName="1.0" >  
    6.   
    7.     <uses-sdk  
    8.         android:minSdkVersion="14"  
    9.         android:targetSdkVersion="17" />  
    10.   
    11.     <application  
    12.         android:allowBackup="true"  
    13.         android:icon="@drawable/ic_launcher"  
    14.         android:label="@string/app_name"  
    15.         android:theme="@style/AppTheme" >  
    16.           
    17.     ……  
    18.   
    19.         <service android:name="com.example.servicetest.MyService" >  
    20.         </service>  
    21.     </application>  
    22.   
    23. </manifest>  
    这样的话,一个简单的带有Service功能的程序就写好了,现在我们将程序运行起来,并点击一下Start Service按钮,可以看到LogCat的打印日志如下:
                                                  

    也就是说,当启动一个Service的时候,会调用该Service中的onCreate()和onStartCommand()方法。

    那么如果我再点击一次Start Service按钮呢?这个时候的打印日志如下:

                                              

    可以看到,这次只有onStartCommand()方法执行了,onCreate()方法并没有执行,为什么会这样呢?这是由于onCreate()方法只会在Service第一次被创建的时候调用,如果当前Service已经被创建过了,不管怎样调用startService()方法,onCreate()方法都不会再执行。因此你可以再多点击几次Start Service按钮试一次,每次都只会有onStartCommand()方法中的打印日志。

    我们还可以到手机的应用程序管理界面来检查一下MyService是不是正在运行,如下图所示:

                                             

    恩,MyService确实是正在运行的,即使它的内部并没有执行任何的逻辑。

    回到ServiceTest程序,然后点击一下Stop Service按钮就可以将MyService停止掉了。

    Service和Activity通信

    上面我们学习了Service的基本用法,启动Service之后,就可以在onCreate()或onStartCommand()方法里去执行一些具体的逻辑了。不过这样的话Service和Activity的关系并不大,只是Activity通知了Service一下:“你可以启动了。”然后Service就去忙自己的事情了。那么有没有什么办法能让它们俩的关联更多一些呢?比如说在Activity中可以指定让Service去执行什么任务。当然可以,只需要让Activity和Service建立关联就好了。

    观察MyService中的代码,你会发现一直有一个onBind()方法我们都没有使用到,这个方法其实就是用于和Activity建立关联的,修改MyService中的代码,如下所示:

    [java]  view plain copy
    1. public class MyService extends Service {  
    2.   
    3.     public static final String TAG = "MyService";  
    4.   
    5.     private MyBinder mBinder = new MyBinder();  
    6.   
    7.     @Override  
    8.     public void onCreate() {  
    9.         super.onCreate();  
    10.         Log.d(TAG, "onCreate() executed");  
    11.     }  
    12.   
    13.     @Override  
    14.     public int onStartCommand(Intent intent, int flags, int startId) {  
    15.         Log.d(TAG, "onStartCommand() executed");  
    16.         return super.onStartCommand(intent, flags, startId);  
    17.     }  
    18.   
    19.     @Override  
    20.     public void onDestroy() {  
    21.         super.onDestroy();  
    22.         Log.d(TAG, "onDestroy() executed");  
    23.     }  
    24.   
    25.     @Override  
    26.     public IBinder onBind(Intent intent) {  
    27.         return mBinder;  
    28.     }  
    29.   
    30.     class MyBinder extends Binder {  
    31.   
    32.         public void startDownload() {  
    33.             Log.d("TAG""startDownload() executed");  
    34.             // 执行具体的下载任务  
    35.         }  
    36.   
    37.     }  
    38.   
    39. }  
    这里我们新增了一个MyBinder类继承自Binder类,然后在MyBinder中添加了一个startDownload()方法用于在后台执行下载任务,当然这里并不是真正地去下载某个东西,只是做个测试,所以startDownload()方法只是打印了一行日志。

    然后修改activity_main.xml中的代码,在布局文件中添加用于绑定Service和取消绑定Service的按钮:

    [html]  view plain copy
    1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     android:layout_width="match_parent"  
    3.     android:layout_height="match_parent"  
    4.     android:orientation="vertical" >  
    5.   
    6.     <Button  
    7.         android:id="@+id/start_service"  
    8.         android:layout_width="match_parent"  
    9.         android:layout_height="wrap_content"  
    10.         android:text="Start Service" />  
    11.   
    12.     <Button  
    13.         android:id="@+id/stop_service"  
    14.         android:layout_width="match_parent"  
    15.         android:layout_height="wrap_content"  
    16.         android:text="Stop Service" />  
    17.   
    18.     <Button  
    19.         android:id="@+id/bind_service"  
    20.         android:layout_width="match_parent"  
    21.         android:layout_height="wrap_content"  
    22.         android:text="Bind Service" />  
    23.       
    24.     <Button   
    25.         android:id="@+id/unbind_service"  
    26.         android:layout_width="match_parent"  
    27.         android:layout_height="wrap_content"  
    28.         android:text="Unbind Service"  
    29.         />  
    30.       
    31. </LinearLayout>  
    接下来再修改MainActivity中的代码,让MainActivity和MyService之间建立关联,代码如下所示:
    [java]  view plain copy
    1. public class MainActivity extends Activity implements OnClickListener {  
    2.   
    3.     private Button startService;  
    4.   
    5.     private Button stopService;  
    6.   
    7.     private Button bindService;  
    8.   
    9.     private Button unbindService;  
    10.   
    11.     private MyService.MyBinder myBinder;  
    12.   
    13.     private ServiceConnection connection = new ServiceConnection() {  
    14.   
    15.         @Override  
    16.         public void onServiceDisconnected(ComponentName name) {  
    17.         }  
    18.   
    19.         @Override  
    20.         public void onServiceConnected(ComponentName name, IBinder service) {  
    21.             myBinder = (MyService.MyBinder) service;  
    22.             myBinder.startDownload();  
    23.         }  
    24.     };  
    25.   
    26.     @Override  
    27.     protected void onCreate(Bundle savedInstanceState) {  
    28.         super.onCreate(savedInstanceState);  
    29.         setContentView(R.layout.activity_main);  
    30.         startService = (Button) findViewById(R.id.start_service);  
    31.         stopService = (Button) findViewById(R.id.stop_service);  
    32.         bindService = (Button) findViewById(R.id.bind_service);  
    33.         unbindService = (Button) findViewById(R.id.unbind_service);  
    34.         startService.setOnClickListener(this);  
    35.         stopService.setOnClickListener(this);  
    36.         bindService.setOnClickListener(this);  
    37.         unbindService.setOnClickListener(this);  
    38.     }  
    39.   
    40.     @Override  
    41.     public void onClick(View v) {  
    42.         switch (v.getId()) {  
    43.         case R.id.start_service:  
    44.             Intent startIntent = new Intent(this, MyService.class);  
    45.             startService(startIntent);  
    46.             break;  
    47.         case R.id.stop_service:  
    48.             Intent stopIntent = new Intent(this, MyService.class);  
    49.             stopService(stopIntent);  
    50.             break;  
    51.         case R.id.bind_service:  
    52.             Intent bindIntent = new Intent(this, MyService.class);  
    53.             bindService(bindIntent, connection, BIND_AUTO_CREATE);  
    54.             break;  
    55.         case R.id.unbind_service:  
    56.             unbindService(connection);  
    57.             break;  
    58.         default:  
    59.             break;  
    60.         }  
    61.     }  
    62.   
    63. }  
    可以看到,这里我们首先创建了一个ServiceConnection的匿名类,在里面重写了onServiceConnected()方法和onServiceDisconnected()方法,这两个方法分别会在Activity与Service建立关联和解除关联的时候调用。在onServiceConnected()方法中,我们又通过向下转型得到了MyBinder的实例,有了这个实例,Activity和Service之间的关系就变得非常紧密了。现在我们可以在Activity中根据具体的场景来调用MyBinder中的任何public方法,即实现了Activity指挥Service干什么Service就去干什么的功能。

    当然,现在Activity和Service其实还没关联起来了呢,这个功能是在Bind Service按钮的点击事件里完成的。可以看到,这里我们仍然是构建出了一个Intent对象,然后调用bindService()方法将Activity和Service进行绑定。bindService()方法接收三个参数,第一个参数就是刚刚构建出的Intent对象,第二个参数是前面创建出的ServiceConnection的实例,第三个参数是一个标志位,这里传入BIND_AUTO_CREATE表示在Activity和Service建立关联后自动创建Service,这会使得MyService中的onCreate()方法得到执行,但onStartCommand()方法不会执行。

    然后如何我们想解除Activity和Service之间的关联怎么办呢?调用一下unbindService()方法就可以了,这也是Unbind Service按钮的点击事件里实现的逻辑。

    现在让我们重新运行一下程序吧,在MainActivity中点击一下Bind Service按钮,LogCat里的打印日志如下图所示:

                                             

    另外需要注意,任何一个Service在整个应用程序范围内都是通用的,即MyService不仅可以和MainActivity建立关联,还可以和任何一个Activity建立关联,而且在建立关联时它们都可以获取到相同的MyBinder实例。

    如何销毁Service

    在Service的基本用法这一部分,我们介绍了销毁Service最简单的一种情况,点击Start Service按钮启动Service,再点击Stop Service按钮停止Service,这样MyService就被销毁了,可以看到打印日志如下所示:

                               

    那么如果我们是点击的Bind Service按钮呢?由于在绑定Service的时候指定的标志位是BIND_AUTO_CREATE,说明点击Bind Service按钮的时候Service也会被创建,这时应该怎么销毁Service呢?其实也很简单,点击一下Unbind Service按钮,将Activity和Service的关联解除就可以了。

    先点击一下Bind Service按钮,再点击一下Unbind Service按钮,打印日志如下所示:

                                         

    以上这两种销毁的方式都很好理解。那么如果我们既点击了Start Service按钮,又点击了Bind Service按钮会怎么样呢?这个时候你会发现,不管你是单独点击Stop Service按钮还是Unbind Service按钮,Service都不会被销毁,必要将两个按钮都点击一下,Service才会被销毁。也就是说,点击Stop Service按钮只会让Service停止,点击Unbind Service按钮只会让Service和Activity解除关联,一个Service必须要在既没有和任何Activity关联又处理停止状态的时候才会被销毁。

    为了证实一下,我们在Stop Service和Unbind Service按钮的点击事件里面加入一行打印日志:

    [java]  view plain copy
    1. public void onClick(View v) {  
    2.     switch (v.getId()) {  
    3.     case R.id.start_service:  
    4.         Intent startIntent = new Intent(this, MyService.class);  
    5.         startService(startIntent);  
    6.         break;  
    7.     case R.id.stop_service:  
    8.         Log.d("MyService""click Stop Service button");  
    9.         Intent stopIntent = new Intent(this, MyService.class);  
    10.         stopService(stopIntent);  
    11.         break;  
    12.     case R.id.bind_service:  
    13.         Intent bindIntent = new Intent(this, MyService.class);  
    14.         bindService(bindIntent, connection, BIND_AUTO_CREATE);  
    15.         break;  
    16.     case R.id.unbind_service:  
    17.         Log.d("MyService""click Unbind Service button");  
    18.         unbindService(connection);  
    19.         break;  
    20.     default:  
    21.         break;  
    22.     }  
    23. }  
    然后重新运行程序,先点击一下Start Service按钮,再点击一下Bind Service按钮,这样就将Service启动起来,并和Activity建立了关联。然后点击Stop Service按钮后Service并不会销毁,再点击一下Unbind Service按钮,Service就会销毁了,打印日志如下所示:

                                    

    我们应该始终记得在Service的onDestroy()方法里去清理掉那些不再使用的资源,防止在Service被销毁后还会有一些不再使用的对象仍占用着内存。

    Service和Thread的关系

    不少Android初学者都可能会有这样的疑惑,Service和Thread到底有什么关系呢?什么时候应该用Service,什么时候又应该用Thread?答案可能会有点让你吃惊,因为Service和Thread之间没有任何关系!

    之所以有不少人会把它们联系起来,主要就是因为Service的后台概念。Thread我们大家都知道,是用于开启一个子线程,在这里去执行一些耗时操作就不会阻塞主线程的运行。而Service我们最初理解的时候,总会觉得它是用来处理一些后台任务的,一些比较耗时的操作也可以放在这里运行,这就会让人产生混淆了。但是,如果我告诉你Service其实是运行在主线程里的,你还会觉得它和Thread有什么关系吗?让我们看一下这个残酷的事实吧。

    在MainActivity的onCreate()方法里加入一行打印当前线程id的语句:

    [java]  view plain copy
    1. Log.d("MyService""MainActivity thread id is " + Thread.currentThread().getId());  
    然后在MyService的onCreate()方法里也加入一行打印当前线程id的语句:
    [java]  view plain copy
    1. Log.d("MyService""MyService thread id is " + Thread.currentThread().getId());  

    现在重新运行一下程序,并点击Start Service按钮,会看到如下打印日志:

                                     

    可以看到,它们的线程id完全是一样的,由此证实了Service确实是运行在主线程里的,也就是说如果你在Service里编写了非常耗时的代码,程序必定会出现ANR的。

    你可能会惊呼,这不是坑爹么!?那我要Service又有何用呢?其实大家不要把后台和子线程联系在一起就行了,这是两个完全不同的概念。Android的后台就是指,它的运行是完全不依赖UI的。即使Activity被销毁,或者程序被关闭,只要进程还在,Service就可以继续运行。比如说一些应用程序,始终需要与服务器之间始终保持着心跳连接,就可以使用Service来实现。你可能又会问,前面不是刚刚验证过Service是运行在主线程里的么?在这里一直执行着心跳连接,难道就不会阻塞主线程的运行吗?当然会,但是我们可以在Service中再创建一个子线程,然后在这里去处理耗时逻辑就没问题了。

    额,既然在Service里也要创建一个子线程,那为什么不直接在Activity里创建呢?这是因为Activity很难对Thread进行控制,当Activity被销毁之后,就没有任何其它的办法可以再重新获取到之前创建的子线程的实例。而且在一个Activity中创建的子线程,另一个Activity无法对其进行操作。但是Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例。因此,使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心无法对后台任务进行控制的情况。

    一个比较标准的Service就可以写成:

    [java]  view plain copy
    1. @Override  
    2. public int onStartCommand(Intent intent, int flags, int startId) {  
    3.     new Thread(new Runnable() {  
    4.         @Override  
    5.         public void run() {  
    6.             // 开始执行后台任务  
    7.         }  
    8.     }).start();  
    9.     return super.onStartCommand(intent, flags, startId);  
    10. }  
    11.   
    12. class MyBinder extends Binder {  
    13.   
    14.     public void startDownload() {  
    15.         new Thread(new Runnable() {  
    16.             @Override  
    17.             public void run() {  
    18.                 // 执行具体的下载任务  
    19.             }  
    20.         }).start();  
    21.     }  
    22.   
    23. }  

    创建前台Service

    Service几乎都是在后台运行的,一直以来它都是默默地做着辛苦的工作。但是Service的系统优先级还是比较低的,当系统出现内存不足情况时,就有可能会回收掉正在后台运行的Service。如果你希望Service可以一直保持运行状态,而不会由于系统内存不足的原因导致被回收,就可以考虑使用前台Service。前台Service和普通Service最大的区别就在于,它会一直有一个正在运行的图标在系统的状态栏显示,下拉状态栏后可以看到更加详细的信息,非常类似于通知的效果。当然有时候你也可能不仅仅是为了防止Service被回收才使用前台Service,有些项目由于特殊的需求会要求必须使用前台Service,比如说墨迹天气,它的Service在后台更新天气数据的同时,还会在系统状态栏一直显示当前天气的信息,如下图所示:

                                                       

    那么我们就来看一下如何才能创建一个前台Service吧,其实并不复杂,修改MyService中的代码,如下所示:

    [java]  view plain copy
    1. public class MyService extends Service {  
    2.   
    3.     public static final String TAG = "MyService";  
    4.   
    5.     private MyBinder mBinder = new MyBinder();  
    6.   
    7.     @Override  
    8.     public void onCreate() {  
    9.         super.onCreate();  
    10.         Notification notification = new Notification(R.drawable.ic_launcher,  
    11.                 "有通知到来", System.currentTimeMillis());  
    12.         Intent notificationIntent = new Intent(this, MainActivity.class);  
    13.         PendingIntent pendingIntent = PendingIntent.getActivity(this0,  
    14.                 notificationIntent, 0);  
    15.         notification.setLatestEventInfo(this"这是通知的标题""这是通知的内容",  
    16.                 pendingIntent);  
    17.         startForeground(1, notification);  
    18.         Log.d(TAG, "onCreate() executed");  
    19.     }  
    20.   
    21.     .........  
    22.   
    23. }  
    这里只是修改了MyService中onCreate()方法的代码。可以看到,我们首先创建了一个Notification对象,然后调用了它的setLatestEventInfo()方法来为通知初始化布局和数据,并在这里设置了点击通知后就打开MainActivity。然后调用startForeground()方法就可以让MyService变成一个前台Service,并会将通知的图片显示出来。

    现在重新运行一下程序,并点击Start Service或Bind Service按钮,MyService就会以前台Service的模式启动了,并且在系统状态栏会弹出一个通栏图标,下拉状态栏后可以看到通知的详细内容,如下图所示。

                                                       

    好了,由于篇幅的原因,本篇文章就先写到这里。目前我们已经把关于Service的很多重要知识点都梳理完了,下一篇文章会承接这篇文章,介绍Android Service中剩下的一个非常重要且复杂的知识点 —— 远程Service的使用,感兴趣的朋友请继续阅读 Android Service完全解析,关于服务你所需知道的一切(下) 。

    展开全文
  • android service

    千次阅读 2011-05-24 14:30:00
    service基础service 和activity 一样, 也有一个从启动到销毁的过程,但是Service的声明周期相对要简单些,如下3个阶段: * 创建服务 * 开始服务 * 销毁服务 一个服务实际上是一个继承android.app.Service的类。...

    service基础

     

    service 和activity 一样, 也有一个从启动到销毁的过程,但是Service的声明周期相对要简单些,如下3个阶段:

     

     * 创建服务    * 开始服务  * 销毁服务

     

      一个服务实际上是一个继承android.app.Service的类。当service经历上面3个阶段时候,会调用相应的方法。

      public void onCreate();

      public void onStart(intent intent , int startId);

      public void onDestroy();

     

      一个服务之会创建一次,销毁一次,但可以开始多次。也就是说onCreate() 和OnDestroy()方法只会被执行一次,OnStart()方法可以执行多次。

     

      我们在用服务的时候,不仅要继承service类,重写其中的方法,而且在androidmenifest.xml文件中,我们也应该进行配置。

      在<application>标签中加入如下代码:<service android:enabled="true' android:name=".MyService"/>

      其中android:enabled="true",表示MyService服务处于激活状态,虽然目前MyService是激活的,但是系统不会启动MyService,想要启动服务,必须

      显示的调用startService()方法。停止服务的话,调用显示stopService().

     

     

       关于服务的创建和开始服务,有两点需要注意:

         (1) 编写一个服务类,该类继承android.app.Service类。Service类涉及到三个声明周期,但是这个三个声明周期在子类中并不一定需要完全

                  覆盖,可根据需求取舍。在该类中有一个onBind()抽象方法,该方法是一个抽象方法,在Service()子类中必须覆盖,这个方法在 Service

                  Activity进行绑定的时候被调用。

     

         (2) 在androidmenifest.xml文件中配置<service>标签来对service 进行配置,并将其中的android:enabled属性设置为true.

     

           ( 3 ) 调用startService()方法启动服务。停止服务用stopService().

     

     

      Activity和Service绑定

     

             如果我们仅仅是如上说的,调用startService()方法来启动服务,并未调用stopServie()方法,那么这个服务就会随着android系统的启动而期

             启动,关闭而关闭。就是说该服务启动后就一直在后台运行,直到系统android 系统关闭。如果我们希望在启动服务的activity关闭之后,该

             服务也关闭,那么我们就要将activity于服务绑定。

     

      参考下面:

       

    当一个 Activity 绑定到一个 Service 上时,它负责维护 Service 实例的引用,允许你对正在运行的 Service 进行一些方法调用。

     

     Activity 能进行绑定得益于 Service 的接口。为了支持 Service 的绑定,实现 onBind 方法 如下所示:

     

    private final IBinder binder = new MyBinder();

     

    @Override

    public IBinder onBind(Intent intent) {

    return binder;

    }

     

    public class MyBinder extends Binder {

    MyService getService()

    {

    return MyService.this;

    }

    }

     

    Service Activity 的连接可以用 ServiceConnection 来实现。你需要实现一个新的 ServiceConnection ,重写 onServiceConnected onServiceDisconnected 方法,一旦连接建立,你就能得到 Service 实例的引用。

     

    // Reference to the service

    private MyService serviceBinder;

     

    // Handles the connection between the service and activity

    private ServiceConnection mConnection = new ServiceConnection()

    {

    public void onServiceConnected(ComponentName className, IBinder service) {

    // Called when the connection is made.

    serviceBinder = ((MyService.MyBinder)service).getService();

    }

     

    public void onServiceDisconnected(ComponentName className) {

    // Received when the service unexpectedly disconnects.

    serviceBinder = null;

    }

    };

     

    执行绑定,调用 bindService 方法,传入一个选择了要绑定的 Service Intent (显式或隐式)和一个你实现了的 ServiceConnection 实例,如下的框架代码所示:

     

    @Override

    public void onCreate(Bundle icicle) {

    super.onCreate(icicle);

    // Bind to the service

    Intent bindIntent = new Intent(MyActivity.this, MyService.class);

    bindService(bindIntent, mConnection, Context.BIND_AUTO_CREATE);

    }

     

    以上总结三点

         (1):Service为了支持被绑定,实现了onBind()方法。 并在其中返回一个IBinder对象, IBinder类中

                   有获得SERVICE实例的方法。

         (2):在Activity中实现用于连接SERVICE和Activity的 ServiceConnection, 一旦连接建立,你就能得到 Service 实例的引用。(相对于第三步来说,第二步的实现是具体的操作。)

        (3) 执行绑定,调用 bindService 方法.(相对于第二步来讲,相当于发送命令。)

     

     

    一旦 Service 对象找到,通过 onServiceConnected 处理函数中获得 serviceBinder 对象就能得到它的公共方法和属性。

     

    Android 应用程序一般不共享内存,但在有些时候,你的应用程序可能想要与其它的应用程序中运行的 Service 交互。

     

    你可以使用广播 Intent 或者通过用于启动 Service Intent 中的 Bundle 来达到与运行在其它进程中的 Service 交互的目的。如果你需要更加紧密的连接的话,你可以使用 AIDL Service 跨越程序边界来实现绑定。 AIDL 定义了系统级别的 Service 的接口,来允许 Android 跨越进程边界传递对象。

     

     在BroadcastReceiver中启动service

     

       如上,我们在启动服务的时候都是先启动了一个activity,然后在activity中启动服务。如果是这样的,稍显复杂了。我们能利用

       BroadcastReceiver在系统启动的时候就运行某个服务。这个原理和启动activity 是一样的。

     

        下面是个简单的例子

     

                public class StartupReciver extends BroadcastReceiver{

                      @Override

                       public void onReceive(Context, Intent intent){

                        Intent serviceIntent = new Intent(context,MyService.class);

                        context.startService(serviceIntent);

                        Intent activityIntent = new Intent(context,MessageActivity.class);

                        // 一般我们在BroadcastReceiver中启动activity的话,必须设置如下标识。

                        activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                        startActivity(activityIntent);    

                           }

     

     

              }

     

             上面代码启动了一个服务和一个activity.

     

       在androidmenifest.xml 文件中的配置如下:

     

     

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="net.blogjava.mobile.startupservice" android:versionCode="1"
        android:versionName="1.0">
        <application android:icon="@drawable/icon" android:label="@string/app_name">
            <activity android:name=".MessageActivity"  android:theme="@android:style/Theme.Dialog" >
                <intent-filter>                
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        
            <receiver android:name="StartupReceiver">
                <intent-filter>
                    <action android:name="android.intent.action.BOOT_COMPLETED" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </receiver>
            <service android:enabled="true" android:name=".MyService" />
        </application>
        <uses-sdk android:minSdkVersion="3" />
        
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    </manifest> 

     

     

    展开全文
  • android service

    万次阅读 2010-01-07 13:13:00
    作为一款多任务操作系统,如果不能运行后台服务,显然说不过去,Android 当然提供了运行后台程序的方法。而且非常简单易用,只不过...创建服务类所谓的服务,在Android里被称做 Service,只要继承 android.app.Service

    作为一款多任务操作系统,如果不能运行后台服务,显然说不过去,Android 当然提供了运行后台程序的方法。而且非常简单易用,只不过有一些小问题需要注意,这个主题分为两部分,第一部分是如何实现一个Service以及他的生命周期,第二部分是对于一个个后台服务应该注意的事项。我们开始吧!

    创建服务类

    所谓的服务,在Android里被称做 Service,只要继承 android.app.Service 这个抽象类,并且实现其中几个方法就可以了。

    public class RoidingService extends android.app.Service {}
    里边必须实现的一个方法是 onBind(Intent intent) ,他具体是做什么的我们下边讲。还有两个重要的回调函数需要覆盖,onCreate() 和 onDestroy()。跟 Actitivty 类似,在创建和销毁 Service 时回调这两个函数,达到初始化或退出前保存状态。

    服务的生命周期

    有了 Service 类我们如何启动他呢,有两种方法:

    • Context.startService()
    • Context.bindService()

    在同一个应用任何地方调用 startService() 方法就能启动 Service 了,然后系统会回调 Service 类的 onCreate() 以及 onStart() 方法。这样启动的 Service 会一直运行在后台,直到 Context.stopService() 或者 selfStop() 方法被调用。另外如果一个 Service 已经被启动,其他代码再试图调用 startService() 方法,是不会执行 onCreate() 的,但会重新执行一次 onStart() 。

    另外一种 bindService() 方法的意思是,把这个 Service 和调用 Service 的客户类绑起来,如果调用这个客户类被销毁,Service 也会被销毁。用这个方法的一个好处是,bindService() 方法执行后 Service 会回调上边提到的 onBind() 方发,你可以从这里返回一个实现了 IBind 接口的类,在客户端操作这个类就能和这个服务通信了,比如得到 Service 运行的状态或其他操作。如果 Service 还没有运行,使用这个方法启动 Service 就会 onCreate() 方法而不会调用 onStart()。

     

    与 Service 通信并且让它持续运行

    如果我们想保持和 Service 的通信,又不想让 Service 随着 Activity 退出而退出呢?你可以先 startService() 然后再 bindService() 。当你不需要绑定的时候就执行 unbindService() 方法,执行这个方法只会触发 Service 的 onUnbind() 而不会把这个 Service 销毁。这样就可以既保持和 Service 的通信,也不会随着 Activity 销毁而销毁了。

     

    提高 Service 优先级

    Android 系统对于内存管理有自己的一套方法,为了保障系统有序稳定的运信,系统内部会自动分配,控制程序的内存使用。当系统觉得当前的资源非常有限的时候,为了保 证一些优先级高的程序能运行,就会杀掉一些他认为不重要的程序或者服务来释放内存。这样就能保证真正对用户有用的程序仍然再运行。如果你的 Service 碰上了这种情况,多半会先被杀掉。但如果你增加 Service 的优先级就能让他多留一会,我们可以用 setForeground(true) 来设置 Service 的优先级。

    为什么是 foreground ? 默认启动的 Service 是被标记为 background,当前运行的 Activity 一般被标记为 foreground,也就是说你给 Service 设置了 foreground 那么他就和正在运行的 Activity 类似优先级得到了一定的提高。当让这并不能保证你得 Service 永远不被杀掉,只是提高了他的优先级。

    有一个方法可以给你更清晰的演示,进入 $SDK/tools 运行命令

    返回的一大堆东西,观察 oom_adj 的值,如果是大于 8 一般就是属于 backgroud 随时可能被干掉,数值越小证明优先级越高,被干掉的时间越晚。你看phone的程序是 -12 说明电话就是电话,其他什么都干了了,也的能接电话对吧。另外还有一个 -100 的,更邪乎因为是 system 如果他也完蛋了,你得系统也就挂了,嘿嘿。

     

    用其他方式启动 Service

    其实不光能从 Activity 中启动 Service ,还有一个很有用的方法是接收系统的广播,这就要用到 Receiver 。在 Mainfest 文件中配置你得 Receiver 能接收什么样的广播消息,那么即使你得程序没有显示给用户,你的 Service 也能启动。你要做的就是继承 android.content.BroadcastReceiver ,然后实现 onReceive(Context context, Intent intent) 方法,就可以启动你得 Service 了。这里不能 bindService 因为一个 Receiver 是一个短暂存在的对象,所以 bind 是没有什么意义的。

    资源消耗

    大家都说 G1 的电池太不抗用,这个问题其实我看来跟多是软件的问题。1150毫安的电池不算大,但也不算小了,考虑到 500mhz 的 CPU 还是非常耗电的。因为一个 Service 要长时间后台运行,所以如果你得 Service 太过于消耗资源那电池更用不了多久了。

    对于这个问题我有一点点考虑,和大家分享一下。因为一般 Service 都会启动另外的线程不断循环作一些操作,循环频率不易太高。也不要做太过于耗费资源的操作,特别是CPU资源,因为后台 Service 用户看不到,会比较莫名奇妙。具体可以结合 top 以及 logcat 监测使用情况。LOG中如果虚拟机频繁的 GC 应该也说明程序还有很大改进的余地。因为GC 也是很耗费CPU的。可能这些不光 Service 应该注意,只要是移动设备都应该考虑,才能给你的用户最佳的体验。

     

    原文参见:http://www.roiding.com/index.php/archives/187

    A Service is an application component that runs in the background,not interacting with the user, for an indefinite period of time. Each service class must have a corresponding declaration in its package's AndroidManifest.xml. Services can be started with Context.startService() and Context.bindService(). Note that services, like other application objects, run in the main thread of their hosting process. This means that, if your service is going to do any CPU intensive (such as MP3 playback) or blocking (such as networking) operations, it should spawn its own thread in which to do that work.
    展开全文
  • 在上一篇文章中,我们学习了Android Service相关的许多重要内容,包括Service的基本用法、Service和Activity进行通信、Service的销毁方式、Service与Thread的关系、以及如何创建前台Service。以上所提到的这些知识点...

    转载请注册出处:http://blog.csdn.net/guolin_blog/article/details/9797169


    在上一篇文章中,我们学习了Android Service相关的许多重要内容,包括Service的基本用法、Service和Activity进行通信、Service的销毁方式、Service与Thread的关系、以及如何创建前台Service。以上所提到的这些知识点,基本上涵盖了大部分日常开发工作当中可能使用到的Service技术。不过关于Service其实还有一个更加高端的使用技巧没有介绍,即远程Service的用法。使用远程Service甚至可以实现Android跨进程通信的功能,下面就让我们具体地学习一下。


    如果你还没有看过前面一篇文章,建议先去阅读一下 Android Service完全解析,关于服务你所需知道的一切(上) ,因为本篇文章中涉及到的代码是在上篇文章的基础上进行修改的。


    在上篇文章中我们知道了,Service其实是运行在主线程里的,如果直接在Service中处理一些耗时的逻辑,就会导致程序ANR。


    让我们来做个实验验证一下吧,修改上一篇文章中创建的ServiceTest项目,在MyService的onCreate()方法中让线程睡眠60秒,如下所示:

    public class MyService extends Service {
    
    	......
    
    	@Override
    	public void onCreate() {
    		super.onCreate();
    		Log.d(TAG, "onCreate() executed");
    		try {
    			Thread.sleep(60000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    	
    	......
    
    }

    重新运行后,点击一下Start Service按钮或Bind Service按钮,程序就会阻塞住并无法进行任何其它操作,过一段时间后就会弹出ANR的提示框,如下图所示。



    之前我们提到过,应该在Service中开启线程去执行耗时任务,这样就可以有效地避免ANR的出现。


    那么本篇文章的主题是介绍远程Service的用法,如果将MyService转换成一个远程Service,还会不会有ANR的情况呢?让我们来动手尝试一下吧。


    将一个普通的Service转换成远程Service其实非常简单,只需要在注册Service的时候将它的android:process属性指定成:remote就可以了,代码如下所示:

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

    现在重新运行程序,并点击一下Start Service按钮,你会看到控制台立刻打印了onCreate() executed的信息,而且主界面并没有阻塞住,也不会出现ANR。大概过了一分钟后,又会看到onStartCommand() executed打印了出来。


    为什么将MyService转换成远程Service后就不会导致程序ANR了呢?这是由于,使用了远程Service后,MyService已经在另外一个进程当中运行了,所以只会阻塞该进程中的主线程,并不会影响到当前的应用程序。


    为了证实一下MyService现在确实已经运行在另外一个进程当中了,我们分别在MainActivity的onCreate()方法和MyService的onCreate()方法里加入一行日志,打印出各自所在的进程id,如下所示:


    Log.d("TAG", "process id is " + Process.myPid());

    再次重新运行程序,然后点击一下Start Service按钮,打印结果如下图所示:



    可以看到,不仅仅是进程id不同了,就连应用程序包名也不一样了,MyService中打印的那条日志,包名后面还跟上了:remote标识。


    那既然远程Service这么好用,干脆以后我们把所有的Service都转换成远程Service吧,还省得再开启线程了。其实不然,远程Service非但不好用,甚至可以称得上是较为难用。一般情况下如果可以不使用远程Service,就尽量不要使用它。


    下面就来看一下它的弊端吧,首先将MyService的onCreate()方法中让线程睡眠的代码去除掉,然后重新运行程序,并点击一下Bind Service按钮,你会发现程序崩溃了!为什么点击Start Service按钮程序就不会崩溃,而点击Bind Service按钮就会崩溃呢?这是由于在Bind Service按钮的点击事件里面我们会让MainActivity和MyService建立关联,但是目前MyService已经是一个远程Service了,Activity和Service运行在两个不同的进程当中,这时就不能再使用传统的建立关联的方式,程序也就崩溃了。


    那么如何才能让Activity与一个远程Service建立关联呢?这就要使用AIDL来进行跨进程通信了(IPC)。


    AIDL(Android Interface Definition Language)是Android接口定义语言的意思,它可以用于让某个Service与多个应用程序组件之间进行跨进程通信,从而可以实现多个应用程序共享同一个Service的功能。


    下面我们就来一步步地看一下AIDL的用法到底是怎样的。首先需要新建一个AIDL文件,在这个文件中定义好Activity需要与Service进行通信的方法。新建MyAIDLService.aidl文件,代码如下所示:

    package com.example.servicetest;
    interface MyAIDLService {
    	int plus(int a, int b);
    	String toUpperCase(String str);
    }

    点击保存之后,gen目录下就会生成一个对应的Java文件,如下图所示:


     


    然后修改MyService中的代码,在里面实现我们刚刚定义好的MyAIDLService接口,如下所示:

    public class MyService extends Service {
    
    	......
    
    	@Override
    	public IBinder onBind(Intent intent) {
    		return mBinder;
    	}
    
    	MyAIDLService.Stub mBinder = new Stub() {
    
    		@Override
    		public String toUpperCase(String str) throws RemoteException {
    			if (str != null) {
    				return str.toUpperCase();
    			}
    			return null;
    		}
    
    		@Override
    		public int plus(int a, int b) throws RemoteException {
    			return a + b;
    		}
    	};
    
    }

    这里先是对MyAIDLService.Stub进行了实现,重写里了toUpperCase()和plus()这两个方法。这两个方法的作用分别是将一个字符串全部转换成大写格式,以及将两个传入的整数进行相加。然后在onBind()方法中将MyAIDLService.Stub的实现返回。这里为什么可以这样写呢?因为Stub其实就是Binder的子类,所以在onBind()方法中可以直接返回Stub的实现。


    接下来修改MainActivity中的代码,如下所示:

    public class MainActivity extends Activity implements OnClickListener {
    
    	private Button startService;
    
    	private Button stopService;
    
    	private Button bindService;
    
    	private Button unbindService;
    	
    	private MyAIDLService myAIDLService;
    
    	private ServiceConnection connection = new ServiceConnection() {
    
    		@Override
    		public void onServiceDisconnected(ComponentName name) {
    		}
    
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service) {
    			myAIDLService = MyAIDLService.Stub.asInterface(service);
    			try {
    				int result = myAIDLService.plus(3, 5);
    				String upperStr = myAIDLService.toUpperCase("hello world");
    				Log.d("TAG", "result is " + result);
    				Log.d("TAG", "upperStr is " + upperStr);
    			} catch (RemoteException e) {
    				e.printStackTrace();
    			}
    		}
    	};
    
    	......
    
    }

    我们只是修改了ServiceConnection中的代码。可以看到,这里首先使用了MyAIDLService.Stub.asInterface()方法将传入的IBinder对象传换成了MyAIDLService对象,接下来就可以调用在MyAIDLService.aidl文件中定义的所有接口了。这里我们先是调用了plus()方法,并传入了3和5作为参数,然后又调用了toUpperCase()方法,并传入hello world字符串作为参数,最后将调用方法的返回结果打印出来。


    现在重新运行程序,并点击一下Bind Service按钮,可以看到打印日志如下所示:




    由此可见,我们确实已经成功实现跨进程通信了,在一个进程中访问到了另外一个进程中的方法。


    不过你也可以看出,目前的跨进程通信其实并没有什么实质上的作用,因为这只是在一个Activity里调用了同一个应用程序的Service里的方法。而跨进程通信的真正意义是为了让一个应用程序去访问另一个应用程序中的Service,以实现共享Service的功能。那么下面我们自然要学习一下,如何才能在其它的应用程序中调用到MyService里的方法。


    在上一篇文章中我们已经知道,如果想要让Activity与Service之间建立关联,需要调用bindService()方法,并将Intent作为参数传递进去,在Intent里指定好要绑定的Service,示例代码如下:

    Intent bindIntent = new Intent(this, MyService.class);
    bindService(bindIntent, connection, BIND_AUTO_CREATE);
    这里在构建Intent的时候是使用MyService.class来指定要绑定哪一个Service的,但是在另一个应用程序中去绑定Service的时候并没有MyService这个类,这时就必须使用到隐式Intent了。现在修改AndroidManifest.xml中的代码,给MyService加上一个action,如下所示:
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.servicetest"
        android:versionCode="1"
        android:versionName="1.0" >
    
        ......
    
        <service
            android:name="com.example.servicetest.MyService"
            android:process=":remote" >
            <intent-filter>
                <action android:name="com.example.servicetest.MyAIDLService"/>
            </intent-filter>
        </service>
    
    </manifest>

    这就说明,MyService可以响应带有com.example.servicetest.MyAIDLService这个action的Intent。


    现在重新运行一下程序,这样就把远程Service端的工作全部完成了。


    然后创建一个新的Android项目,起名为ClientTest,我们就尝试在这个程序中远程调用MyService中的方法。


    ClientTest中的Activity如果想要和MyService建立关联其实也不难,首先需要将MyAIDLService.aidl文件从ServiceTest项目中拷贝过来,注意要将原有的包路径一起拷贝过来,完成后项目的结构如下图所示:




    然后打开或新建activity_main.xml,在布局文件中也加入一个Bind Service按钮:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
         >
    
       <Button 
           android:id="@+id/bind_service"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:text="Bind Service"
           />
    
    </LinearLayout>
    接下来打开或新建MainActivity,在其中加入和MyService建立关联的代码,如下所示:
    public class MainActivity extends Activity {
    
    	private MyAIDLService myAIDLService;
    
    	private ServiceConnection connection = new ServiceConnection() {
    
    		@Override
    		public void onServiceDisconnected(ComponentName name) {
    		}
    
    		@Override
    		public void onServiceConnected(ComponentName name, IBinder service) {
    			myAIDLService = MyAIDLService.Stub.asInterface(service);
    			try {
    				int result = myAIDLService.plus(50, 50);
    				String upperStr = myAIDLService.toUpperCase("comes from ClientTest");
    				Log.d("TAG", "result is " + result);
    				Log.d("TAG", "upperStr is " + upperStr);
    			} catch (RemoteException e) {
    				e.printStackTrace();
    			}
    		}
    	};
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		Button bindService = (Button) findViewById(R.id.bind_service);
    		bindService.setOnClickListener(new OnClickListener() {
    			@Override
    			public void onClick(View v) {
    				Intent intent = new Intent("com.example.servicetest.MyAIDLService");
    				bindService(intent, connection, BIND_AUTO_CREATE);
    			}
    		});
    	}
    
    }

    这部分代码大家一定会非常眼熟吧?没错,这和在ServiceTest的MainActivity中的代码几乎是完全相同的,只是在让Activity和Service建立关联的时候我们使用了隐式Intent,将Intent的action指定成了com.example.servicetest.MyAIDLService。


    在当前Activity和MyService建立关联之后,我们仍然是调用了plus()和toUpperCase()这两个方法,远程的MyService会对传入的参数进行处理并返回结果,然后将结果打印出来。


    这样的话,ClientTest中的代码也就全部完成了,现在运行一下这个项目,然后点击Bind Service按钮,此时就会去和远程的MyService建立关联,观察LogCat中的打印信息如下所示:



    不用我说,大家都已经看出,我们的跨进程通信功能已经完美实现了。


    不过还有一点需要说明的是,由于这是在不同的进程之间传递数据,Android对这类数据的格式支持是非常有限的,基本上只能传递Java的基本数据类型、字符串、List或Map等。那么如果我想传递一个自定义的类该怎么办呢?这就必须要让这个类去实现Parcelable接口,并且要给这个类也定义一个同名的AIDL文件。这部分内容并不复杂,而且和Service关系不大,所以就不再详细进行讲解了,感兴趣的朋友可以自己去查阅一下相关的资料。


    好了,结合上下两篇,这就是关于Service你所需知道的一切。


    关注我的技术公众号,每天都有优质技术文章推送。关注我的娱乐公众号,工作、学习累了的时候放松一下自己。

    微信扫一扫下方二维码即可关注:

            

    展开全文
  • 在官方文档Android 8.0 行为变更中有这样一段话: Android 8.0 有一项复杂功能;系统不允许后台应用创建后台服务。 因此,Android 8.0 引入了一种全新的方法,即Context.startForegroundService(),以在前台启动新...
  • 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的Android程序员如果连Service都没听说过的话,那确实也太逊了。Service作为Android四大组件之一,在每一个应用程序中都扮演着非常重要的角色。它主要...
  • 37.Android Service 及 AIDL

    千次阅读 2015-11-18 17:56:22
    37.Android Service 及 AIDLAndroid Service 及 AIDL Android Service介绍 Android Service类型 Android Service bind 和 start Local Service 实现 Remote Service 实现Android Service介绍├── Context │ ├─...
  • Android Service与BroadcastReceiver、bindService示例详解,代码非常详细,详解博客网址:http://blog.csdn.net/sunboy_2050/article/details/7364024
  • Android Service讲解 和 aidl 实现

    千次阅读 2016-11-10 16:46:23
    Android Service讲解 和 aidl 实现代码下载 Android Service讲解 和 aidl 实现一、Android Service1.建立一个serviceservice和activity很相识,只是service在后台运行,activity在前台运行,他们都属于同一个同一个...
  • Service 1.Service基础知识概述   Service(服务)是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件。服务可由其他应用组件启动(如Activity),服务一旦被启动将在后台一直运行,即使启动服务...
  • Android Service实现详细过程

    千次阅读 2012-02-28 13:46:27
    一、Android Service介绍 AndroidService分为两种:Android Service和Native ServiceAndroid Service:又称为Java Service,是实现在框架层(framework)里的Server。Android Service以Java编写。 Native ...
  • Android service 实现过程

    万次阅读 2010-09-15 22:05:00
    一、Android Service介绍 AndroidService分为两种:Android Service和Native ServiceAndroid Service:又称为Java Service,是实现在框架层(framework)里的Server。Android Service以Java...
  • Android service 启动篇之 startService

    万次阅读 2018-08-31 16:28:10
    Androidservice 详解中说明了大概背景,这里不再过叙述了。 代码基于Android O Android基础总结之六:Sevice中是应用端对于service 使用的总结,其中看到启动service 需要的接口有startService 和bindService...
  • android service demo

    千次下载 热门讨论 2014-04-30 16:36:49
    import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.util.Log; public class ServiceDemo extends Service { private static final String TAG = "Service...
  • Android Service启动到Activity

    千次阅读 2017-04-06 09:30:26
    Android Service启动到Activity从Service启动到Activity基本可以分为两类: 1.从自己应用的Service启动自己应用的Activity,即显式意图; 2.从自己应用的Service启动到其他应用的Activity,或者从别的应用的Service...
  • android service 后台执行定时任务

    万次阅读 多人点赞 2016-03-06 18:07:50
    关于service 大家应都知道是android 四大组件之一,用来执行后台任务的。 如果还不太了解service 可以看看郭大神写的Android Service完全解析,关于服务你所需知道的一切,...
  • Android Service用法详解

    千次阅读 2012-06-28 19:56:16
    ServiceAndroid 系统中的一种组件,它和Activity的级别差不多,但又Activity不同,它是不能与用户交互的,但可以和其他组件进行交互。它不能自己运行,只能后台运行。 Service的特点:没有可视的UI、后台...
  • android service生命周期

    万次阅读 2012-03-26 14:55:03
    1、Android service如果是由activity bindService启动,则service自己的onCreate(),onBind(),onServiceConnected()按照这个顺序被调用,则在该activity调用onDestroy()方法时不论是否调用unBindService方法,...
  • Android Service详解(三)---IntentService

    万次阅读 2016-11-11 09:59:48
    Android Service详解(三)---IntentService 这是第三篇文章主要讲的是IntentService的使用 回顾: Android Service详解(一)---概述和StartService Android Service详解(二)---StartService  一、Service的耗时...
  • Android四大组件之Android Service的用法

    千次阅读 2009-10-24 08:03:00
    Android ServiceAndroid四大组件之一,运行在后台,不可见。 Android Service生命周期相关方法:onCreate,onStartCommand,onBind,onUnbind,onDestroy
  • Android service中弹出dialog 权限变动与用法 专注于Android开发,分享经验总结,欢迎加入 最近在做音视频聊天需要在service中弹出聊天界面,开发期间遇到的坑特此记录(Android9系统) 报错信息有如下: Caused by...
  • Android Service使用

    千次阅读 2019-07-01 10:34:11
    ServiceAndroid四大组件之一,与Activity的职责相反,Service一般在后台处理一些耗时任务,或者一直执行某个任务。 Service使用 新建一个计时Service。 public class TimerService extends Service { private ...
  • android四大组件--android service详解

    千次阅读 2014-04-26 13:25:23
    一、android service简介 1、Android中的服务和windows中的服务是类似的东西,服务一般没有用户操作界面,它运行于系统中不容易被用户发觉,可以使用它开发如监控之类的程序。 2、在Android中,Activity主要负责...
  • Android Service详解(四)---绑定服务BoundService详解之AIDL的使用 这是第四篇文章主要讲的是绑定服务BoundService之AIDL的使用 回顾: Android Service详解(一)---概述和StartService Android Service详解(二)--...
  • Android Service详解(四)---绑定服务BoundService详解之扩展Binder类 这是第四篇文章主要讲的是BoundService中使用扩展Binder类实现 回顾 Android Service详解(一)---概述和StartService Android ...
  • Android service进程保护

    万次阅读 2016-05-11 14:16:23
    一,基本概念1.什么才叫应用进程保活应用进程保活可以理解为应用位于后台永远不能被杀死。...对于Android 5.0以前的系统我们可以考虑以上两种情况下的后台常驻,而对于Android 5.0以及以后的版本我们只能基
  • Android Service 同时使用bindservice和startservice启动的问题今天,突然在一个技术群里,有个人说了他在面试中遇到的变态问题,其中就有一个是关于serviceq启动的问题,我当时也不是很了解就随口说了一个答案,...
  • Android Service 弹出系统全局Dialog

    千次阅读 2015-07-09 11:12:22
    Android Service中弹出全局Dialog对话框是一个很古老的问题。 很久之前解决过,但没有记录,今天遇到的时候又纠结了会儿。搜了下资料,千篇一律的解决方法无非是:dialog.getWindow().setType(WindowManager....
  • Android Service ANR

    千次阅读 2017-09-18 10:26:36
    误区:很多人以为service 能执行耗时的操作,这是一个误区,service 中不能执行耗时的操作,它也属于UI主线程,要执行耗时操作可以使用IntentService http://blog.csdn.net/zhf198909/article/details/6906786...
  • Android Service实现闹钟

    千次阅读 2016-06-01 21:49:43
    AndroidService实现闹钟

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 342,946
精华内容 137,178
关键字:

androidservice