启动服务(Service)和调用服务里的方法

本文深入解析Android中的Service组件,探讨其生命周期、启动方式及其应用场景。文章对比了Service与Activity的区别,强调了Service作为后台组件的重要性,并详细介绍了startService的生命周期及如何正确地在Service中执行耗时操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<span style="color: rgb(34, 34, 34); font-family: 'Comic Sans MS'; font-size: 18px; line-height: 19px; background-color: rgb(249, 249, 249);">service与activity一样都存在与当前进程的主线程中,所以,一些阻塞UI的操作,比如耗时操作不能放在service里进行,比如另外开启一个线程来处理诸如网络请求的耗时操作。如果在service里进行一些耗CPU和耗时操作,可能会引发ANR警告,这时应用会弹出是强制关闭还是等待的对话框。所以,对service的理解就是和activity平级的,只不过是看不见的,在后台运行的一个组件,这也是为什么和activity同被说为Android的基本组件。</span>

/**
 * Created by Administrator on 2015/8/23.
 * startService()
 * 服务的生命周期:onCreate(),onStartCommand(),onDestroy()。
 * 调用服务里的方法
 */
public class StartServiceActivity extends FragmentActivity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_startmyservice);
    }
    public void startService(View view){
        Intent intent = new Intent(this,MySelfService.class);
        startService(intent);
    }
    /**
     * start方式开启服务的生命周期:onCreate>onStartCommand(onStart过时)>onDestroy
     * start方式开启服务,服务被开启后,就跟开启者没有任何关系了,假如开启者销毁了,挂了,任务栈
     * 清空了,服务仍然在后台长期运行。
     * 通过start方式开启服务,要调用服务的方法只能将服务当做普通的类来看待,因此一些普通的方法可以被调用,但是一些
     * 跟服务有关的方法在被调用时会报错。
     * @author Administrator
     *
     */
    public void invokeMethod(View view){
        MySelfService service = new MySelfService();
        service.methodInService(this);
    }
}

/**
 * 为什么使用服务:
 * 首先进程在,子线程就在。
 * Android应用程序一旦被打开,通常情况下关闭(按后退键其实是清空任务栈)应用程序进程不会关闭,
 * 可进DDMS看到进程仍然存在,因此子线程仍在运行,当你在DDMS中把进程stop后,进程才停止,子线程
 * 也就停止了,另外,当系统内存不足时,这些进程可能被系统回收,因此在Activity里用子线程不是一个
 * 好的选择。
 * 对于Android系统,进程有5个优先级:
 * Foreground process前台进程:用户正在使用的进程(可获取到焦点),例如你正在玩微信等;此时该应用属于前台进程。
 * Visible process可视进程:用户仍然能看到的进程(可见,但没有获取焦点),例如,透明的Activity后面的那个应用就是可视进程;
 * Service process服务进程,应用程序有服务正在运行,此时,该应用属于服务进程;
 * Background process后台进程:应用程序没有服务在运行,并且最小化,即Activity不可见;此时该应用是后台进程;
 * empty process空进程:任务栈是空的,即没有Activity在运行,也没有服务在运行,此时该应用是空进程。例如本案例;为什么使用服务
 *
 * 由上可知,不建议在Activity写子线程,也就是说不建议在Activity访问网络,因为一旦任务栈空了,就属于
 * 空进程,易被系统回收,建议在服务里写子线程,这样提高了进程的优先级,使进程不易被系统回收,即便进程被回
 *收了,在内存充足时,该进程又会恢复,服务也会被重新创建,先执行服务的onCreate方法,再执行服务的onStartCommand方法。
 *
 *
 *
 *  startService():如果服务还没有被创建,则先创建再启动,即先执行服务的onCreate方法再执行服务的onStartCommand方法,
 * 如果服务已经存在则只执行onStartCommand方法。
 * 当服务正在运行的时候,服务所在进程被系统回收了时(这不太可能,因为服务进程优先级较高),在系统内存充足时该进程又会
 * 恢复,服务也会被重新创建先执行服务的onCreate方法再执行onStartCommand方法。这可通过在DDMS终止掉服务所在进程来验证(此时不执行onDestroy方法)。
 *   但是如果通过Android系统的设置里面的正在运行的服务管理点stop按钮终止服务时,服务就不会重新创建了,就真的终
 *  止了,同时执行了服务的onDestroy方法,此时在DDMS中你会发现该应用的进程还在。
 * 如上面的情况,如果在设置里stop掉服务或者说服务被销毁了之后,进程被系统回收或在DDMS中关闭了进程,之后即使系统充足了,
 * 进程也不会恢复,当然服务更不会被重建。后面可知道可通过广播或守护线程来让服 务被stop时立刻重新创建。
 */
public class MySelfService extends Service {
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        System.out.println("MySelfService服务被创建");
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        System.out.println("MySelfService服务接收到启动的指令");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        System.out.println("MySelfService服务被销毁");
        super.onDestroy();
    }
    public void methodInService(Context context){
        Toast.makeText(context,"我是服务里的方法,但此时我只是把服务当成一个普通的类看待",Toast.LENGTH_SHORT).show();
        //这样在Activity调用 的时候会报错,因为通过普通方式调用服务,只能把服务作为普通的类看待
//        Toast.makeText(this,"我是服务里的方法,但此时我只是把服务当成一个普通的类看待",Toast.LENGTH_SHORT).show();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值