Activity和Service的区别

本文详细介绍了Android中Activity和Service的区别与用法。Activity作为应用程序的主要界面,通过Fragment和布局创建UI,其生存周期包括活动、暂停、停止和非活动状态。Service则用于在后台运行任务,可以通过startService和bindService启动,bindService还能实现与Service的绑定交互。文章通过实例代码展示了如何创建和管理Activity与Service。

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

一、Activity

      在应用程序中至少包含一个用来处理应用程序的主UI功能的主界面屏幕。这个主界面一般由多个Fragment组成,并由一组次要Activity支持。要在屏幕之间切换,就必须要启动一个新的Activity。一般的Activity都占据了整个显示屏,但可以创建成半透明或二者浮动的Activity。

1、Activity的创建

      通过继承Activity类可以创建一个Activity窗口,基本框架如下:

public class MyActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}

      以上代码是一个空的Activity,可以通过使用Fragment、布局和视图来创建UI。视图是用来显示数据和提供交互交互的UI控件。Android提供给了多个布局类,成为ViewGroup,它可以包含多个视图来帮助UI布局。Fragment用来封装UI的各个部分,从而能够方便的创建动态界面,这些界面能够针对不同的屏幕尺寸很方向重新排列,起到优化UI的效果。

  要想把一个UI分配给一个Activity,需要在onCreate()方法中调用setContentView()方法。可以通过在java代码中创建布局,也可以通过调用xml布局资源文件来创建。如下两种方式:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    TextView tvShow = new TextView(this);
    setContentView(tvShow);
    tvShow.setText("你好");
}
      当然,通过调用xml布局文件来创建UI的方法更常用,如下:
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState);      
    setContentView(R.layout.activity_main);
}

      最后,创建好了Activity类不要忘了在Manifest中对其注册。

  需要注意的是,想让一个Activity可以被应用程序启动器使用,它必须包含一个监听MAIN动作和LAUNCHER分类的Intent-Filter,如下:

<activity
  android:name="com.codingblock.myactivity.MyActivity"
   android:label="@string/app_name" >
    <intent-filter>
       <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
       </intent-filter>
</activity>

2、Activity的生存周期

      (1)Activity栈:每一个Activity的状态是由他在Activity栈中所处的位置所决定的,Activity栈是当前所有正在运行的Activity的后进先出的集合。当一个新Activity启动,它就会变成Activity状态,并移到栈顶,当返回到前一个Activity,前台Activity被关闭,那么站总的下一个Activity就会移动到栈顶,变成活动状态。

      (2)Activity状态

      随着Activity的创建和销毁,从栈中移进移出的过程中他们经历了如下4种可能的状态:
  · 活动状态:当一个Activity处于栈顶是,它是可见的、具有焦点的前台Activity并可以接受用户输入。
  · 暂停状态:Activity可见,但没有焦点,不能接受用户输入事件。(例如:当一个透明的或者非全屏的Activity位于该Activity之前时)
  · 停止状态:Activity不可见。此时,Activity仍然会保留在内存中,保存所有状态信息,然而当系统的其他地方要求使用使用内存时,会优先终止此类状态的Activity。

  · 非活动状态:Activity被终止。此时Activity已经从栈中移除了。

      (3)监控状态改变

      为了保证Activity可以对状态改变做出反应,Android提供了一系列的回调方法,当Activity的状态改变时它们就会被触发。以下代码是整个Activity生存期的框架,各方法的说明已在代码注释中详细给出:

public class MyActivity extends Activity {
    
    //在完整生存期开始调用
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //初始化Activity并填充UI
    }
    
    //在onCreate方法完成后调用,用于恢复UI状态
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        /* 
         * 从savedInstanceState恢复UI状态
         * 这个Bundle也被传递给了onCreate
         * 自Activity上次可见之后,只有系统终止了该Activity时,才会被调用
         */
    }
    
    //在随后的Activity进程可见生存期之前调用
    @Override
    protected void onRestart() {
        super.onRestart();
        //加载改变,知道Activity在此进程中已经可见
    }
    
    //在可见生存期的开始时调用
    @Override
    protected void onStart() {
        super.onStart();
        //既然Activity可见,就应用任何要求的UI Change
    }

    //在Activity状态生存期开始时调用
    @Override
    protected void onResume() {
        super.onResume();
        /*
         * 恢复Activity需要,但是当它处于不活动状态时被挂起的暂停的UI更新、线程或进程
         * 在Activity状态生命周期结束的时候滴啊用,用来保存UI状态的改变
         */
    }

    //在UI状态改变保存到saveInstanceState
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        /*
         * 如果进程被运行时终止并被重启,
         * 那么这个Bundle将被传递给onCreate和onRestoreInstanceState
         */
    }

    //在Activity状态生存期结束时调用
    @Override
    protected void onPause() {
        super.onPause();
        /*
         * 挂起不需要更新的UI更新、线程或者CPU密集的进程
         * 当Activity不是前台的活动状态的Activity时
         */
    }

    //在可见生存期结束时调用
    @Override
    protected void onStop() {
        super.onStop();
        /*
         * 挂起不需要的UI更新、线程或处理
         * 当Activity不可见时,保存所有的编辑或者状态改变,因为在调用这个方法后,京城可能会被终止
         */
    }

    //在完整生存期结束时调用
    @Override
    protected void onDestroy() {
        super.onDestroy();
        /*
         * 清理所有的资源,包括结束线程、
         * 关闭数据库连接等
         */
    }
}

二、Service

1、Service的创建

      在创建Service时,步骤与Activity很像:
  1.继承Service,创建Service子类。
  2.在AndroidManifest.xml文件中配置该Service。
      下面创建一个最基本的Service组件:MyService.java

public class MyService extends Service {
    
    //必须实现的方法,用户返回Binder对象
    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("--onBind()--");
        return null;
    }
    
    //创建Service时调用该方法,只调用一次
    @Override
    public void onCreate() {
        super.onCreate();
        System.out.println("--onCreate()--");
    }
    
    //每次启动Servcie时都会调用该方法
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        System.out.println("--onStartCommand()--");
        return super.onStartCommand(intent, flags, startId);
    }
    
    //解绑Servcie调用该方法
    @Override
    public boolean onUnbind(Intent intent) {
        System.out.println("--onUnbind()--");
        return super.onUnbind(intent);
    }
    
    //退出或者销毁时调用该方法
    @Override
    public void onDestroy() {
        System.out.println("--onDestroy()--");
        super.onDestroy();
    }
    
}

      然后再Manifest.xml文件中红配置一下

<service 
     android:name=".MyService">
</service>

      为了待会测试的方便,我们在该Service的onCreate()方法里面写一个方法,开启一个线程,让其不断输出“Service运行中”的状态。补充后的MyService类如下:

public class MyService extends Service {
    
    private boolean serviceRunning = false;
    // 必须实现的方法,用户返回Binder对象
    @Override
    public IBinder onBind(Intent intent) {
        System.out.println("--onBind()--");
        return null;
    }

    // 创建Service时调用该方法,只调用一次
    @Override
    public void onCreate() {
        super.onCreate();
        System.out.println("--onCreate()--");
        serviceRunning = true;
        new Thread() {
            @Override
            public void run() {
                while (serviceRunning) {
                    System.out.println("---Service运行中---");
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
        }.start();
    }

    // 每次启动Servcie时都会调用该方法
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        System.out.println("--onStartCommand()--");
        return super.onStartCommand(intent, flags, startId);
    }

    // 解绑Servcie调用该方法
    @Override
    public boolean onUnbind(Intent intent) {
        System.out.println("--onUnbind()--");
        return super.onUnbind(intent);
    }

    // 退出或者销毁时调用该方法
    @Override
    public void onDestroy() {
        serviceRunning = false;
        System.out.println("--onDestroy()--");
        super.onDestroy();
    }

}

      代码分析:首先我们定义一个boolean类型的变量serviceRunning,用来控制新线程中是否输出“---Service运行中---”,通过这样的方式更能让我们直观地看到Servcie的运行状态。

2、启动Service

      启动Service和启动一个Activity类似,也是先定义一个Intent让它指向需要启动Service,然后通过调用startService()方法,启动即可,具体代码如下:

btn_start_service.setOnClickListener(new OnClickListener() {
     @Override
     public void onClick(View arg0) {
         intent = new Intent(this, MyService.class);
         startService(intent);
        }
});

      代码分析:在主界面中添加了一个按钮,在按钮中首先定义了一个Intent,然后通过startService启动该Intent从而就可以启动Service,与启动一个Activity的方法一模一样。

3、停止Service

      与启动Service相对应的就是停止Service,通过stopService()即可完成此操作,如下:
btn_stop_service.setOnClickListener(new OnClickListener() {
     @Override
     public void onClick(View arg0) {
         stopService(intent);
         }
});

      当然,这里Intent需要与startService使用的为一个。

4、绑定Service

      绑定Service用是通过调用bindService(Intent service, ServiceConnection conn, int flags)方法来实现的,单看参数就知道与启动Service比起来,会麻烦一些,大体分为如下三步:

      第一步:重写onBind()方法,返回Service实例
  Service可以让Activity绑定,以获得更加详细的接口。如果先想让一个Service支持绑定,需要实现Service中得onBind()方法,并返回被绑定Service的当前实例,如下:

public IBinder onBind(Intent intent) {
        System.out.println("--onBind()--");
        return new MyBinder();
    }
    
    public class MyBinder extends Binder{
        MyService getService(){
            return MyService.this;
    }
       第二步:实现一个ServiceConnection  
  另外,Service和其他组件的链接表示为一个ServiceConnection,要想一个Service和其他组件绑定,需要实现一个新的ServiceConnection,建立一个链接后,就可以通过重写onServiceConnected()方法和onServiceDisconnected()方法,来获得对Service实例的引用。代码如下:
MyService.MyBinder binder = null;
class MyServiceConn implements ServiceConnection {
        // 服务被绑定成功之后执行
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //service为onBind方法返回的Service实例
            binder = (MyService.MyBinder) service;
        }
        
        // 服务奔溃或者被杀掉执行
        @Override
        public void onServiceDisconnected(ComponentName name) {
       binder = null;
        }
}

       第三步:调用bindService执行绑定Service
  要想绑定需要给bindService()除了需要给他传递一个需要的Intent和一个ServiceConnection实例外,还需要指定一个标示,如下:

btn_bind_service.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                bindService(intent, myServiceConn, Context.BIND_AUTO_CREATE);
            }
});

      其中,myServiceConn为第二步中MyServiceConn实例,Context.BIND_AUTO_CREATE即为标示。

5、解绑Service

      解绑Service是通过unbindService实现的,如下:

btn_unbind_service.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                if (binder != null) {
                    unbindService(myServiceConn);
                }
            }
});
      这里需要注意的是,unbindService方法中传入的ServiceConnection实例一定要跟绑定时的一致,否则可能会导致程序崩溃。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值