Android基础知识(二)|青训营笔记

232 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的第3天。

2 Fragment

2.1 Fragment是什么

Fragment是一个轻量级页面容器,设计之初是为了解决屏幕碎片化问题,能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用得非常广泛。Fragment是依赖于Activity的,不能独立存在,可以在一个Activity中组合多个Fragment,从而实现多窗格界面,也可以在多个Activity中重复使用某个Fragment,可以将Fragment视为Activity的模块化组成,

这是之前做的一个Fragment练习的界面截图,在整个界面截图中有两个Fragment,左边的是标题栏Fragment,右边是内容Fragment,这两个Fragment嵌入在一个Activity中。

image-20220728205126714.png

2.2 Fragment基本用法

2.2.1 创建Fragment

  1. 创建一个Fragment的子类

  2. 在这个子类中重写onCreateView()方法,在该方法中通过调用LayouInflater对象中的inflate()方法加载布局

    代码如下所示:

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.news_content_frag,container,false);
        return view;
    }
    

2.2.2 将Fragment添加到Activity中

  • 静态添加

    使用标签在Activity布局文件中添加Fragment,示例代码如下:

    <!-- 上一层布局为LinearLayout-->
    <fragment
        android:id="@+id/left_fragment"
        android:name="cn.edu.jssvc.wangyu.myframenttest.LeftFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1" />
    
  • 动态添加

    第一步:在Activity布局文件中,可以声明一个FrameLayout作为Fragment的容器,代码如下:

    <FrameLayout
        android:id="@+id/right_layout"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:background="#03A9F4">
    

    第二步:将Fragment添加到创建的容器内

    //创建待添加的Fragment实例
    RightFragment rightFragment = new RightFragment();
    //获取FragmentManager
    FragmentManager fragmentManager = getSupportFragmentManager();
    //开启一个事务
    FragmentTransaction transaction = fragmentManager.beginTransaction();
    //向容器内添加或替换Fragment
    transaction.replace(R.id.right_layout,rightFragment);
    //提交事务
    transaction.commit();
    

2.2.3 Fragment与Activity交互

  • 组件获取

    • Fragment获取Activity中的组件:getActivity().findViewById(R.id.xxx)
    • Activity获取Fragment中的组件:getFragmentManager.findFragmentById(R.id.fragment_xxx)
  • 数据传递

    • Activity传递数据给Fragment:setArguments(Bundle bundle)
    • Fragment传递数据给Activity
      • 通过对象直接传递(方法调用/接口调用)
      • 通过Viewmodel / handler / broadcast / eventbus等通信

2.3 Fragment的生命周期

2.3.1 Fragment的4种生命周期状态

  • Active 运行状态

  • Pause 暂停状态

  • Stop 停止状态

  • Killed 消亡状态

2.3.2 Fragment生命周期的回调方法

  • onAttach():当Fragment和Activity建立关联时调用
  • onCreateView():为Fragment创建视图(加载布局)时调用
  • onActivityCreated():确保与Fragment相关联的Activity已经创建完毕是时调用
  • onDestoryView():当与Fragment关联的视图被移除时调用
  • onDetach():当Fragment和Activity解除关联时调用

2.3.3 Fragment生命周期小结

  • 启动:onAtttach()→onCreate()→onCreateView()→onActivityCreated()→onStart()→onResume()→Resumed
  • 退出:Resumed→onPause()→onStop()→onDestoryView()→onDestory()→onDetach()
  • 部分遮挡:Resumed→onPause()→Paused
  • 部分遮挡恢复:Paused→onResume()→Resumed
  • 完全遮挡:Resumed→onPause()→onStop()→onDestoryView()
  • 完全遮挡恢复:onCreateView()→onActivityCreated()→onStart()→onResumed()→Resumed

注:Fragment生命周期可通过FragmentTransaction.setMaxLifecycle()手动干预

image-20220729205835846.png

3 Service

3.1 Service是什么

serice是Android中实现程序后台运行的解决方案,它非常适合执行那些不需要和用户交互而且还需要长期运行的任务。Service的运行不依赖于任何用户界面,即使程序被切换到后台,或者用户打开了另外一个应用应用程序,Service依然能够保持正常运行。

3.2 Service基本用法

3.2.1 定义一个Service

在AndroidStudio中,右击包名→New→Service→Service,最后会弹出一个如下窗口:

ps:Exported属性表示是否将这个Service暴露给外部其他程序访问,Enabled属性表示是否启动这个Service

image-20220729221621048.png

3.2.2 声明Service

在AndroidMainfest.xml中使用标签可进行Service的声明,用上述方法定义Service会自动声明,示例如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>

    <application
        ...>
        <service
            android:name=".MyService3"
            android:enabled="true"
            android:exported="true" />
            ...
        </activity>
    </application>

</manifest>

3.2.3 启动、停止、绑定和解绑Service

  • 启动服务

    // 创建显式Intent,指定要启动的Service类
    Intent startIntent = new Intent(this, MyService.class);
    startService(startIntent); // 启动服务
    
  • 停止服务

    Intent stopIntent = new Intent(this, MyService.class);
    stopService(stopIntent); // 停止服务
    
  • 绑定

    Intent bindIntent = new Intent(this, MyService.class);
    bindService(bindIntent, connection, BIND_AUTO_CREATE); // 绑定服务
    

    connection是ServiceConnection的实例

  • 解绑

    unbindService(connection); // 解绑服务
    

3.2.4 Service与Activity通信

  1. 定义Binder子类,并实现getService()方法,返回Service对象

    class DownloadBinder extends Binder {
    
        public void startDownload() {
            Log.d("MyService", "startDownload executed");
        }
    
        public int getProgress() {
            Log.d("MyService", "getProgress executed");
            return 0;
        }
    
    }
    
  2. 实现Service类onBind()方法,返回上述Binder对象

    private DownloadBinder mBinder = new DownloadBinder();
    ...
    @Override
        public IBinder onBind(Intent intent) {
            Log.d("MyService", "onBind executed");
            return mBinder;
        }
    
  3. 实例化ServiceConnection对象,实现onServiceConnected()方法

    private ServiceConnection connection = new ServiceConnection() {
    
        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            downloadBinder = (MyService.DownloadBinder) service;
            downloadBinder.startDownload();
            downloadBinder.getProgress();
        }
    };
    
  4. Activity中调用bindService(),并传递步骤3的ServiceConnection对象

    Intent bindIntent = new Intent(this, MyService.class);
    bindService(bindIntent, connection, BIND_AUTO_CREATE); // 绑定服务
    
  5. Activity可以通过调用Service实例中的方法进行直接通信

3.2.5 Service生命周期内的一些回调方法

  • onCreate():服务正在创建中
  • onStartCommand():调用了startService,服务正在启动
  • onBind():客户端绑定到具有bindService()的服务
  • onUnbind():所有客户端都使用unbindService()取消绑定
  • onRebind():客户端绑定到具有bindService()的服务,onUnbind()已经被调用
  • onDestory:该服务不再使用并被销毁