Android Service 问题总结

简介:

http://www.cnblogs.com/foreal/archive/2012/05/08/2490633.html

学习了一下Service,网上常见的一些就不说了,说一下感觉容易给人造成误解的地方

 

1. 如Service的创建都是在新进程创建的么?

 

其实不是的,在 Dev Guide中写道:

Caution: A service runs in the main thread of its hosting process—the service does not create its own thread and does not run in a separate process (unless you specify otherwise). This means that, if your service is going to do any CPU intensive work or blocking operations (such as MP3 playback or networking), you should create a new thread within the service to do that work. By using a separate thread, you will reduce the risk of Application Not Responding (ANR) errors and the application's main thread can remain dedicated to user interaction with your activities.

就是说,当创建一个Service的时候,默认是在Application的进程里主UI线程创建的,如果你在Service中进行阻塞的操作,会直接阻塞UI线程,可能导致五秒无响应的提醒,所以官方建议是在Service里面创建新的线程来防止阻塞放生。

 

2. 如何在新进程里创建Service?

一般的方法就是在manifast中声明Service的时候,使用process标签,注明所使用的进程,默认使用当前程序主进程:

<service 
    android:name="org.foreal.MusicServiceTest"
    android:enabled="true" 
    android:process=":music_process"
></service>

 

其中如果进程的名字时以 ":"开头的,说明进程是当前程序的私有进程,其他程序无法访问,如果是以小写字母开头的进程,说明进程是一个全局的进程,多个程序都可访问此进程,达到多程序共享进程的目的。

 

3.如果不用新进程的Service,如何方便的进行一些阻塞操作?

可以继承IntentService来编写自己的Service,IntentService会自动创建一个worker thread,来进行操作如:

复制代码
public class MyIntentService extends IntentService {
    
    private final static String TAG = "MyIntentService"; 

    public MyIntentService() {
        super("MyIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i(TAG, "onHandleIntent");
        
        try {
            synchronized (this){
                wait(3000);
            }
            Log.i(TAG, "完成一次");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
复制代码

其中只需要重写onHandleIntent方法来处理自己的操作就行,其中每一次的操作都会进去队列中,按顺序串行执行。

其中要注意的是,IntentService在执行完队列中所有操作以后会自动销毁当前Service,也就是说,如果你onHandleIntent中是个非阻塞操作的话,很可能每次调用结束以后Service都被销毁,然后下次在建立新的Service。

此类可以很方便的完成大多数工作,但是如果要进行并发操作的Service,此类就不适合,应自己实现。

 

3. 如何使Service私有?


如果在Service中声明intent filter,那么其他程序也可以通过你声明的intent filter来访问你的Service,为了避免这种情况,首先你可以去掉intent filter,每次调用Service都使用Intent(Context, Class)的形式,但是,如果喜欢用intent filter的形式,可以使用exported标签,来使Service私有,这样即使定义intent filter,其他程序也无法访问。

 

4.如果一个Service在startService以后 又进行了bindService那么他的生命周期是怎样的,stopService能否结束掉Service?

答案是不能的,如果一个Service进行了bind操作,那么再进行stopService是无法结束掉此Service,知道绑定的Context全部结束,或解除绑定,Service才会被结束。

 

5. Service 中Onstart方法中,参数startid是什么意思,又有什么用处?

因为在使用startService开启一个Service以后,必须手动的关闭Service,所以Service可能自己调用 stopSelf 方法,来在任务完成的时候结束掉自己。

但是这个时候就会出现一个问题,如果startService调用了2次,那么就执行了两次onStart操作,在第一次onStart操作结束以后,Service可能会认为任务已经完成,并结束掉自己,这个时候第二次的onStart可能还没结束,导致了任务还未完成就被强行关闭了。

而startid代表当前onStart被调用的一个编号,在结束Service时候,调用stopSelf(startid),这样Service就可以检查,此startid是否是最近一次调用的,如果是,那么才结束Service,否则不结束。


相关文章
Android 11 添加Service服务SELinux问题
Android 11 添加Service服务SELinux问题
542 1
Android基础知识:请解释Service是什么,它与IntentService的区别是什么?
Android基础知识:请解释Service是什么,它与IntentService的区别是什么?
169 0
Android Studio App开发之服务Service的讲解及实战(包括启动和停止,绑定与解绑,推送服务到前台实现音乐播放器,附源码)
Android Studio App开发之服务Service的讲解及实战(包括启动和停止,绑定与解绑,推送服务到前台实现音乐播放器,附源码)
1221 0
43. 【Android教程】服务:Service
43. 【Android教程】服务:Service
94 2
Android Service Call /dev/xxx SELinux
Android Service Call /dev/xxx SELinux
197 1
Android平台GB28181设备接入模块实现后台service按需回传摄像头数据到国标平台侧
我们在做Android平台GB28181设备对接模块的时候,遇到这样的技术需求,开发者希望能以后台服务的形式运行程序,国标平台侧没有视频回传请求的时候,仅保持信令链接,有发起视频回传请求或语音广播时,打开摄像头,并实时回传音视频数据或接收处理国标平台侧发过来的语音广播数据。
|
11月前
|
Android Service之设备存储空间监控 DeviceStorageMonitorService
Android Service之设备存储空间监控 DeviceStorageMonitorService
195 2
Android如何在Activity和Service之间传递数据
Android如何在Activity和Service之间传递数据
376 3
|
11月前
|
Android Service的两种使用方法
Android Service的两种使用方法
84 2

热门文章

最新文章

下一篇
oss创建bucket