jetpack组件最简明实践

jetpack

提供最简单的jetpack架构组件集成使用步奏

  • DataBinding
  • Room
  • Lifecycle
  • LiveData
  • Navigation
  • ViewModel
  • WorkManager

启用jetpack

  • gradle.properties中添加使用androidx
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app's APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true

DataBinding

  • 开启DataBinding
android {
	...
    buildFeatures {
        dataBinding = true
    }
    ...
    }
  • xml布局用Layout包裹
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        ...

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
  • Activity/Fragment 添加binding生成的view
    @Override
    public View getChildView() {
        mBinding = ActivityFootprintBinding.inflate(getLayoutInflater());
        mBinding.setPage(this);
        return mBinding.getRoot();
    }
  • xml中定义dada,定义variable,使用variable提供的属性或方法
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="page"
            type="com.sgm.factorytest.ui.FootprintActivity" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
  • Activity/Fragment 使用binding获取控件
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mAdapter = new FootprintItemAdapter(mFootprintList, this);
        mBinding.rv.setLayoutManager(new LinearLayoutManager(this));
        mBinding.rv.setAdapter(mAdapter);

        initData();
    }

Room

  • 添加依赖
annotationProcessor 'androidx.room:room-compiler:2.2.5'
implementation 'androidx.room:room-runtime:2.2.5'
  • 定义Entity

@Entity
public class Footprint {
    @PrimaryKey(autoGenerate = true)
    private int uid;

    @ColumnInfo(name = "timestamp")
    private long timestamp;

    @ColumnInfo(name = "time")
    private String time;

    @ColumnInfo(name = "page")
    private String page;

    @ColumnInfo(name = "event")
    private String event;

    @ColumnInfo(name = "parameter")
    private String parameter;
    
    ...
    //需要实现get、set方法供room使用
}
  • 定义Dao
@Dao
public interface FootprintDao {
    @Query("SELECT * FROM footprint")
    List<Footprint> getAll();

    @Query("SELECT * FROM footprint WHERE uid IN (:footprintIds)")
    List<Footprint> loadAllByIds(int[] footprintIds);

    @Query("SELECT * FROM footprint WHERE time LIKE :time")
    Footprint findByTime(String time);

    @Query("SELECT * FROM footprint WHERE event LIKE :event")
    Footprint findByEvent(String event);

    @Insert
    void insertAll(Footprint... footprints);

    @Delete
    void delete(Footprint footprint);
}
  • 定义DataBase
@Database(entities = {Footprint.class}, version = 1,exportSchema = false)
public abstract class AppDatabase extends RoomDatabase {
    public abstract FootprintDao footprintDao();
}
  • 使用database获取dao,使用dao里定义的方法
//创建全局db对象
AppDatabase db = Room.databaseBuilder(this, AppDatabase.class, DATABASE_NAME).allowMainThreadQueries().build();

//调用数据库方法
db.getAll()
...

Lifecycle

  • 添加依赖
implementation 'androidx.lifecycle:lifecycle-runtime:2.3.0-alpha02'
  • 需要监听生命周期的A类实现LifecycleObserver
public class VcsAudioManager implements LifecycleObserver {
	...
	}
  • 定义监听的事件需要调用的方法,使用注解标注监听的事件
public class VcsAudioManager implements LifecycleObserver {

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    public void onDestroy() {
		...
    }
    ...
}
  • 在持有lifecycle的B类添加观察者:A类对象,getLifecycle().addObserver(.)
public class VcsAudioActivity extends BaseActivity {

	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getLifecycle().addObserver(VcsAudioManager.instance());
        ...
        }
        ...
}

LiveData

  • 添加依赖
implementation 'androidx.lifecycle:lifecycle-runtime:2.3.0-alpha02'
  • 创建LiveData对象
public MutableLiveData<Footprint> footprintData1 = new MutableLiveData();
  • 在观察的数据变动时,post变动的数据
    public void getFootprint() {
        Footprint footprint1 = App.getFootprintDao().loadById(new Random().nextInt(App.getFootprintDao().getAll().size()-1));
        footprintData1.postValue(footprint1);
  • 在需要地方触发变动
secondViewModel.getFootprint();
  • 在使用地方添加观察者,响应数据变动
      secondViewModel.footprintData1.observe(getViewLifecycleOwner(), new Observer<Footprint>() {
            @Override
            public void onChanged(Footprint footprint) {
                binding.title.setText(footprint.toString());
            }
        });

Navigation

  • 添加依赖
implementation 'androidx.navigation:navigation-fragment:2.3.5'
implementation 'androidx.navigation:navigation-ui:2.3.5'
  • 创建nav_graph.xml导航文件
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/nav_graph"
    app:startDestination="@id/nav1_dest">
    ...
    </navigation>
  • 创建Activity,xml中定义容器,添加属性
    • name
    • defaultNavHost
    • navGraph
<androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"

        app:defaultNavHost="true"
        app:navGraph="@navigation/nav_graph"
        />
  • 文件中添加注册支持的fragment,每个fragment添加支持的action
    • 跳转的目的地
    • 跳转动画
	    <fragment
        android:id="@+id/nav1_dest"
        android:name="com.sgm.factorytest.ui.navigation.NavFragment1"
        tools:layout="@layout/fragment_nav1_dest"
        android:label="nav1"
        >
        <action
            android:id="@+id/action_nav1_dest_to_nav2_dest"
            app:destination="@id/nav2_dest"
            app:enterAnim="@anim/fragment_fade_enter"
            app:exitAnim="@anim/fragment_fade_exit"
            app:popEnterAnim="@android:anim/slide_in_left"
            app:popExitAnim="@android:anim/slide_out_right" />
        <action
            android:id="@+id/action_nav1_dest_to_nav3_dest"
            app:destination="@id/nav3_dest" />
    </fragment>
  • 在fragment中调用Navigation方法,实现跳转
//通过定义的action跳转
Navigation.findNavController(binding.getRoot()).navigate(R.id.action_nav1_dest_to_nav2_dest);

//回退到之前的栈
Navigation.findNavController(binding.getRoot()).popBackStack(R.id.nav1_dest, false);

ViewModel

  • 添加依赖
implementation 'androidx.lifecycle:lifecycle-runtime:2.3.0-alpha02'
  • 继承原生ViewModel
public class SecondViewModel extends ViewModel {
	...
}
  • 在activity/fragment中得到ViewModel对象
SecondViewModel secondViewModel = getDefaultViewModelProviderFactory().create(SecondViewModel.class);
  • 在activity/fragment中使用ViewModel的属性和方法
//调用方法
secondViewModel.getFootprint();

//调用属性,添加监听
secondViewModel.footprintData1.observe(...)

WorkManager

  • 添加依赖
implementation 'androidx.work:work-runtime:2.4.0'
  • AWorker继承Worker
public abstract class BaseWorker extends Worker {

    public BaseWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
       ...
    }

    @NonNull
    @Override
    public Result doWork() {
        return Result.success();//返回当前处理结果状态
    }
    ...
}
  • 在Worker子类的doWork()方法中实现后台任务
public abstract class BaseWorker extends Worker {
    private static final String TAG = "BaseWorker";

    public BaseWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
        Data inputData = workerParams.getInputData();
        String startTime = inputData.getString(AppWorkerManager.WORKER_DATA_KEY);
        Log.e(TAG, startTime);
    }

    @NonNull
    @Override
    public Result doWork() {
        printWorker();
        return Result.success();
    }

    abstract void printWorker();
}

public class AWorker extends BaseWorker{
    private static final String TAG = "AWorker";

    public AWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
    }

    @Override
    void printWorker() {
        Log.e(TAG, "printWorker");
    }
}

  • 创建OneTimeWorkRequest
public OneTimeWorkRequest initOneTimeWorker(Class<? extends ListenableWorker> workerClass) {
        Data data = new Data.Builder()
                .putString(WORKER_DATA_KEY, TimeFormatUtils.getDate(System.currentTimeMillis()))
                .build();

        return new OneTimeWorkRequest
                .Builder(workerClass)
                .setInputData(data)//可以不设置
                .build();
    }
  • 使用WorkManager开始处理worker
WorkManager.getInstance(App.context()).enqueue(initOneTimeWorker(AWorker.class));

版权声明:本文为weixin_46911118原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。