四大组件中的Activity、Service

1.Activity

1.1如何创建Activity

AS创建的(省略很多过程)(必须掌握)

AS创建Activity省略了哪些过程?(理解)

  1. xml文件

  2. java文件,并在java文件中 继承 AppCompatActivity,在onCreate()方法中,setContentView() ,将java文件跟xml文件连接在一起

  3. androidManifest.xml文件中注册Activity

1.2Activity之间的跳转

假设 MainActivity.java MainActivity2.java

从MainActivity.java 跳转到 MainActivity2.java

// 常用的方法
Intent intent = new Intent(MainActivity.this, MainActivity2.class);
startActivity(intent);

// 另外一种方法
Intent intent = new Intent();
intent.setClass(MainActivity.this, MainActivity2.class);
startActivity(intent);

 从MainActivity2.java 跳转到 MainActivity.java

Intent intent = new Intent(MainActivity2.this, MainActivity.class);
startActivity(intent);

// 如果从MainActivity2.java 跳转到 MainActivity.java,MainActivity2不需要存活了
finish();

1.3Activity之间跳转的时候如何传值

传单个的值

 

传对象

 

 1.4Activity生命周期

初次打开app onCreate() onStart() onResume()

隐藏app onPause() onStop()

打开隐藏的app onRestart() onStart() onResume()

退出app onPause() onStop onDestroy()

详细内容请看Activity生命周期_好心boy的博客-CSDN博客_activity生命周期

2.Service

2.1Service简介

  • Service是Android四大组件之一,它可以在后台执行长时间运行操作而没有用户界面的应用组件。

  • Service的启动方式有两种:startService启动和bindService启动。

注意:服务与其他应用程序对象一样,在其托管进程的主线程中运行。这意味着,如果你的服务要执行任何CPU密集型(例如 MP3 播放)或阻塞(例如网络)操作,它应该在Service中再创建一个子线程,然后在这里去处理耗时操作就没问题了。

2.2如何创建一个Service

2.3Service构成

  • MyService.java

package com.hopu.demo;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}
  • AndroidManifest.xml

    <application
            ...>
            <service
                android:name=".MyService"
                android:enabled="true"
                android:exported="true"></service>
    
            <activity
                android:name=".MainActivity"
                android:exported="true">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>	

    2.4Service启动方式

1.startService

启动Service

显式启动通过类名称来启动,需要在Intent中指明Service所在的类,并调用startService (lntent)启动service,显式启动代码如下:

Intent intentStart = new Intent(ServiceActivity.this, StartService.class);
startService(intentStart);

在上面的代码中,Intent指明了启动的Service所在类为StartService。

通过该方式启动Service,访问者与Service之间没有关联,即使访问者退出了,Service也仍然运行。

停止service

显式启动停止Service,需要将启动Service的Intent传递给stopService (Intent)函数,代码如下:

stopService(intentStart);

举个栗子:

1.创建StartService.java继承自Service类,重写onCreate()方法、onStartCommand()方法、onBind()方法、onDestroy()方法,其代码如下:

public class StartService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e(getClass().getName(), "onCreate");
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(getClass().getName(), "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onDestroy() {
        Log.e(getClass().getName(), "onDestroy");
        super.onDestroy();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

2.创建ServiceActivity.java,其代码如下:

public class ServiceActivity extends AppCompatActivity  {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_service);
        Intent intentStart = new Intent(ServiceActivity.this, StartService.class);
        findViewById(R.id.btn_start).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startService(intentStart);
            }
        });
        findViewById(R.id.btn_stop).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopService(intentStart);
            }
        });
    }
}

3.配套的activity_service.xml文件,其代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_bg"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/color_666666">
    <Button
        android:id="@+id/btn_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="start启动服务"/>
    <Button
        android:id="@+id/btn_stop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="start停止服务"/>
</LinearLayout>

4.添加Service组件声明,在AndroidManifest.xml文件中声明一个Service组件,其代码如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.scc.demo">
    <application
        ...>
        <activity
           ...>
            <intent-filter>
                ...
            </intent-filter>
        </activity>
        <service android:name=".service.StartService"/>
    </application>
</manifest>

5.运行结果

06-21 16:41:11.474 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonCreate
06-21 16:41:11.481 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonStart
06-21 16:41:11.482 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonResume
06-21 16:41:13.313 E/-SCC-com.scc.demo.service.StartService: onCreate
06-21 16:41:13.334 E/-SCC-com.scc.demo.service.StartService: onStartCommand
06-21 16:41:16.705 E/-SCC-com.scc.demo.service.StartService: onDestroy

3.BindService

3.1

使用bindService()方法启动Service

绑定模式使用bindService()方法启动Service,其格式如下:

bindService(Intent service,ServiceConnection conn,int flags);

其中的参数说明如下:

  • service:该参数通过Intent指定需要启动的service。

  • conn:该参数是ServiceConnnection对象,当绑定成功后,系统将调用serviceConnnection的onServiceConnected ()方法,当绑定意外断开后,系统将调用ServiceConnnection中的onServiceDisconnected方法。

  • flags:该参数指定绑定时是否自动创建Service。如果指定为BIND_AUTO_CREATE,则自动创建,指定为0,则不自动创建。

绑定方式中,当调用者通过bindService()函数绑定Service时,onCreate()函数和onBinde ( )函数将被先后调用。

  • 通过该方式启动Service,访问者与Service绑定在一起,访问者一旦退出了,Service也就终止了。

  • 使用unbindService()方法取消绑定

    取消绑定仅需要使用unbindService()方法,并将ServiceConnnection传递给unbindService()方法。

    但需要注意的是,unbindService()方法成功后,系统并不会调用onServiceConnected(),因为onServiceConnected()仅在意外断开绑定时才被调用。

    当调用者通过unbindService()函数取消绑定Service时,onUnbind()函数将被调用。如果onUnbind()函数返回true,则表示重新绑定服务时,onRebind ()函数将被调用。

举个栗子:

1.创建BindService.java继承自Service类,重写onCreate()方法、onBind()方法、onUnbind()方法、onDestroy()方法,实现本地通知栏显示,其代码如下:

public class BindService extends Service {
    //声明IBinder接口的一个接口变量mBinder
    public final IBinder mBinder = new LocalBinder();
    private NotificationManager mNM;
    private int NOTIFICATION = R.string.local_service_started;
    //LocalBinder是继承Binder的一个内部类
    public class LocalBinder extends Binder {
        public BindService getService() {
            return BindService.this;
        }
    }
    @Override
    public void onCreate() {
        mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
        Log.e(getClass().getName(), "onCreate");
        showNotification();
    }

    @Override
    public void onDestroy() {
        Log.e(getClass().getName(), "onDestroy");
        mNM.cancel(NOTIFICATION);
        Toast.makeText(this, R.string.local_service_stopped, Toast.LENGTH_SHORT).show();
    }
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(getClass().getName(), "onBind");
        return mBinder;
    }
    @Override
    public boolean onUnbind(Intent intent) {
        Log.e(getClass().getName(), "onUnbind");
        return super.onUnbind(intent);
    }
    private void showNotification() {
        String CHANNEL_ID = "channel_01";//应用频道Id唯一值, 长度若太长可能会被截断,
        String CHANNEL_NAME = "channel_test";//最长40个字符,太长会被截断
        
        CharSequence text = getText(R.string.local_service_started);
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, ServiceActivity.class), 0);
        Notification notification = new NotificationCompat.Builder(this,CHANNEL_ID)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setTicker(text)
                .setWhen(System.currentTimeMillis())
                .setContentTitle(getText(R.string.local_service_label))
                .setContentText(text)
                .setContentIntent(contentIntent)
                .build();
        //Android 8.0 以上需包添加渠道
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ID,
                    CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
            mNM.createNotificationChannel(notificationChannel);
        }
        mNM.notify(NOTIFICATION, notification);
        Log.e(getClass().getName(), "通知栏已出");
    }
}

2.创建ServiceActivity.java,其代码如下:

public class ServiceActivity extends AppCompatActivity {
    private BindService bindService;
    private boolean isBind = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_service);
        findViewById(R.id.btn_bind).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!isBind) {
                    Intent intentBind = new Intent(ServiceActivity.this, BindService.class);
                    bindService(intentBind, serviceConnection, Context.BIND_AUTO_CREATE);
                    isBind = true;
                }
            }
        });
        findViewById(R.id.btn_unbing).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isBind) {
                    isBind = false;
                    unbindService(serviceConnection);
                    bindService = null;
                }
            }
        });
    }

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e(getClass().getName(), "onServiceConnected");
            bindService = ((BindService.LocalBinder) service).getService();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e(getClass().getName(), "onServiceDisconnected");
            bindService = null;
        }
    };
}

3.配套的activity_service.xml文件,其代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_bg"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/color_666666">
    <Button
        android:id="@+id/btn_bind"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="bind服务绑定"/>
    <Button
        android:id="@+id/btn_unbing"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="bind解除绑定"/>
</LinearLayout>

4.添加Service组件声明,在AndroidManifest.xml文件中声明一个Service组件,其代码如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.scc.demo">
    <application
        ...>
        <activity
           ...>
            <intent-filter>
                ...
            </intent-filter>
        </activity>
        <service android:name=".service.BindService"/>
    </application>
</manifest>

5.运行结果

6-21 17:00:04.309 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonCreate
06-21 17:00:04.350 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonStart
06-21 17:00:04.350 E/-SCC-: com.scc.demo.actvitiy.ServiceActivityonResume
06-21 17:00:10.088 E/-SCC-com.scc.demo.service.BindService: onCreate
06-21 17:00:10.120 E/-SCC-com.scc.demo.service.BindService: 通知栏已出
06-21 17:00:10.145 E/-SCC-com.scc.demo.service.BindService: onBind
06-21 17:00:10.164 E/-SCC-com.scc.demo.actvitiy.ServiceActivity$5: onServiceConnected
06-21 17:00:39.111 E/-SCC-com.scc.demo.service.BindService: onUnbind
06-21 17:00:39.134 E/-SCC-com.scc.demo.service.BindService: onDestroy

3.2Service的生命周期

 onBind() 是Service必须实现的方法,返回的IBinder对象相当于Service组件的代理对象,Service允许其他程序组件通过IBinder对象来访问Service内部数据,这样即可实现其他程序组件与Service之间的通信。

3.3startService和bindService的区别

startService:

onCreate() 当Service第一次被创建时,由系统调用。

onStartCommand() 当startService方法启动Service时,该方法被调用。

onDestroy() 当Service不再使用时,由系统调用。

注意:一个startService只会创建一次,销毁一次,但可以开始多次,因此,onCreate()和onDestroy()方法只会被调用一次,而onStart()方法会被调用多次。

bindService:

onCreate() 当Service被创建时,由系统调用。

onBind() 当bindService方法启动Service时,该方法被调用。

onUnbind() 当unbindService方法解除绑定时,该方法被调用。

onDestroy() 当Service不再使用时,由系统调用。

注意:一个bindService可以创建多次,销毁多次,重复使用。

猜你喜欢

转载自blog.csdn.net/weixin_53431933/article/details/125900936