Jetpack介紹

走進Jetpack組件庫

  • 什么是Jetpack
  • Jetpack的優(yōu)勢
  • 為什么要使用Jetpack
  • Jetpack眾多優(yōu)秀組件介紹
  • 使用Jetpack架構開發(fā)

什么是Jetpack組件

  • 概括:Jetpack是眾多優(yōu)秀組件的集合嫁怀,是Google推出一套引領Android開發(fā)的逐一統(tǒng)一開發(fā)規(guī)范的架構

Jetpack的優(yōu)勢

  • 基于生命周期的感知叛复,可以減少NPE崩潰铣耘、內存泄漏温算、模板代碼岗钩。為我們開發(fā)出健壯且高質量的程序提供強力保障
  • 組件可以單獨使用申眼,也可以搭配使用谬晕,搭配Kotlin語言特性可以進一步加速開發(fā)

為什么要使用Jetpack

  • 遵循最佳做法

    • Android Jetpack 組件采用最新的設計方法構建宿亡,具有向后兼容性碑诉,可以減少崩潰和內存泄露彪腔。
  • 消除樣板代碼

    • Android Jetpack 可以管理各種繁瑣的 Activity(如后臺任務、導航和生命周期管理)进栽,以便您可以專注于打造出色的應用德挣。
  • 減少不一致

    • 這些庫可在各種 Android 版本和設備中以一致的方式運作,助您降低復雜性泪幌。

Jetpack眾多組件介紹

使用Jetpack組件需要將項目升級到AndoridX
Jetpack 包含一系列 Android 庫盲厌,它們都采用最佳做法并在 Android 應用中提供向后兼容性


jetpack組件

Navigation : 為單個Activity架構而生的端內路由

  • 特性:Activity,F(xiàn)ragment祸泪,Dialog提供路由能力的組件吗浩、導航時可攜帶參數(shù)、指定轉場動畫没隘、支持deepLink頁面直達懂扼、fragment回退棧管理能力
  • 不足之處:十分依賴xml文件,不利于模塊化右蒲,組件化開發(fā)
  • 添加依賴
  def nav_version = "2.3.2"
// Java language implementation
  implementation "androidx.navigation:navigation-fragment:$nav_version"
  implementation "androidx.navigation:navigation-ui:$nav_version"

  // Kotlin
  implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
  implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
  • 路由調轉阀湿,可攜帶參數(shù),指定轉場動畫
NavController navController = navHostFragment.getNavController();
navController.navigate(int resId, Bundle args, NavOptions navOptions)
  • deppLink實現(xiàn)頁面直達能力
navController.handleDeepLink("/**/**")
  • 管理Fragment回退棧
navController.popBackStack(int destinationId, boolean inclusive)

Lifecycles

構建生命周期感知型組件瑰妄,這些組件可以根據(jù) Activity 或 Fragment 的當前生命周期狀態(tài)調整行為陷嘴。

// 添加依賴
api 'androidx.appcompat:appcompat:1.1.0'
api 'androidx.lifecycler:lifecycle-common:2.1.0'

// 用法
class MyObserver : LifecycleObserver {

        @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
        fun connectListener() {
            ...
        }

        @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
        fun disconnectListener() {
            ...
        }
    }

// 宿主需要實現(xiàn)LifecycleOwner接口
class MyFragment : xxx, LifecycleOwner {
       var mLifecycleRegistry = LifecycleRegistry(this)
      
      // 提供宿主Lifecycle對象
       override fun getLifecycle():Lifecycle {
          return mLifecycleRegistry
      } 
}

 getLifecycle().addObserver(MyObserver())//注冊觀察者,觀察宿主生命周期狀態(tài)變化

ViewModel 具備生命周期感知的數(shù)據(jù)存儲組件

具有生命周期感知、頁面配置更改數(shù)據(jù)不會丟失间坐、數(shù)據(jù)共享

// 添加依賴
api 'androidx.appcompat:appcompat:1.1.0'
api 'androidx.lifecycler:lifecycle-viewmodel:2.0.0'
api 'androidx.lifecycle:lifecycle-livedata:2.0.0'

// 使用方式
class MyViewModel : ViewModel() {
    private val users: MutableLiveData<List<User>> by lazy {
        MutableLiveData().also {
            loadUsers()
        }
    }

    fun getUsers(): LiveData<List<User>> {
        return users
    }

    private fun loadUsers() {
        // Do an asynchronous operation to fetch users.
    }
}
// 創(chuàng)建ViewModel
class MyActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        // 創(chuàng)建ViewModel
        val model: MyViewModel by viewModels()
        // 獲取數(shù)據(jù) 灾挨, 更新UI
        model.getUsers().observe(this, Observer<List<User>>{ users ->
            // update UI
        })
    }
}

LiveData 數(shù)據(jù)共享

配合ViewModel使用
特性:支持共享資源、支持粘性事件分發(fā)竹宋、生命周期感知劳澄、確保符合頁面需要的數(shù)據(jù)
不足:粘性時間不能自動取消

MutableLiveData<T> liveData = new MutableLiveData();
//注冊一個跟宿主生命周期綁定的觀察者,宿主銷毀了蜈七,會自動解除注冊
observe(LifecycleOwner owner,Observer<? super T> observer)
//觀察不到宿主生命周期秒拔,不會自動解除注冊  
observeForever(Observer<? super T> observer) 

//以下倆方法都是分發(fā)數(shù)據(jù)給所有的觀察者
//只能用在主線程  
setValue(T value) 
//子線程,主線程都可以使用  
postValue(T value)

Room 輕量級orm數(shù)據(jù)庫飒硅,本質上是一個SQLite抽象層

特性:使用更加簡單(類似于Retrofit)砂缩,通過注解的方式實現(xiàn)相關功能作谚。編譯時自動生成實現(xiàn)類impl

api "android.arch.persistence.room:runtime:1.1.1"
kapt "android.arch.persistence.room:compiler:1.1.1" 


//1. 創(chuàng)建一個操作數(shù)據(jù)庫數(shù)據(jù)的實體層
// 增刪改查
@Dao
public interface UserDao {
    @Query("SELECT * FROM user")
    List<User> getAll();

    @update("update table user set desc=:desc and where user_id = :userId")
    User updateUser(String desc,String userId);

    @Insert
    void insertAll(User... users);

    @Delete
    void delete(User user);
}


//2. 創(chuàng)建數(shù)據(jù)庫
@Database(entities = {User.class}, version = 1)
public abstract class MyDatabase extends RoomDatabase {
    public static MyDatabase mAppDb;
    static{
        mAppDb = Room.databaseBuilder(getApplicationContext(),
        AppDatabase.class, "database-name").build();
    }
  
    public abstract UserDao userDao();
}

//3. 通過數(shù)據(jù)庫單例對象,獲取userDao數(shù)據(jù)操作對象.訪問數(shù)據(jù)庫
mAppDb.userDao().getAll();

DataBinding 是一種工具,數(shù)據(jù)與View的雙向綁定

特性:減少findViewById模版代碼梯轻、空安全判斷食磕、數(shù)據(jù)與視圖雙向綁定尽棕、釋放Fragment/Activity

// 開啟DataBinding
build.gradle中
android {
  
}

<!--xml中databinding的使用-->
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    <data>
        <variable
            name="user"
            type="xxx.User" />
        <import type="xxx.UserManager"></import>
    </data>
    <androidx.constraintlayout.widget.ConstraintLayout>
        <TextView
            android:id="@+id/tvName"
            android:layout_width="200dp"  //不能使用dataBinding動態(tài)綁定
            android:text="@{user.name}"  //單向綁定數(shù)據(jù)變更自動通知UI
            android:textSize="@{@dimen/16sp}"http://資源引用
            android:text="@{user.name+@string/suffix}"  //字符串的拼接需要引用資源 
            android:text="@{UserManager.getUserName()}" //調用靜態(tài)方法,類必須先導入
            android:onClick="@{()-> UserManager.login()}"
          />

      <EditText
            //雙向綁定數(shù)據(jù)變更自動更新UI喳挑,UI變更了也能自動更新user中name的數(shù)據(jù),比單向綁定多個=
            android:text="@={user.name}" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

<layout_user_info_item>
LayoutUserInfoItemBinding binding = DataBindingUtils.inflate(....)

Paging 列表分頁組件滔悉∫了校可以輕松完成分頁預加載達到無限滑動分頁效果

實現(xiàn)基于liveData頁面分頁加載功能
不足之處:不支持列表數(shù)據(jù)增刪改,列表添加HeaderView 和FooterView定位不準確

// 添加依賴
api 'android.arch.paging:runtime:1.0.0'

// 使用方式
//1.構建PagedList.Config對象,用以聲明以何種方式分頁
PagedList.Config config = new PagedList.Config.Builder()
                .setPageSize(10)//指定每次分頁加載的條目數(shù)量
                .setInitialLoadSizeHint(12)//指定初始化數(shù)據(jù)加載的條目數(shù)量
                .build();
//2.創(chuàng)建數(shù)據(jù)源工廠類,用來創(chuàng)建數(shù)據(jù)提供者
DataSource.Factory factory = new DataSource.Factory() {
        @NonNull
        @Override
        public DataSource create() {
           return new ItemKeyedDataSource();
        }
    };

//3.構建一個能夠觸發(fā)加載頁面初始化數(shù)據(jù)的LiveData對象,并且把上面創(chuàng)建的DataSource.Factory和PagedList.Config 傳遞進去
LiveData<PagedList<T>> pageData = new LivePagedListBuilder(factory, config)
                .build();//最后通過build方法 構建出LiveData對象回官。請注意它的 泛型是<PagedList<T>>

//4.最后我們只需要拿到前面構建出來的LiveData對象注冊一個Observer觀察者,僅僅如此就可以觸發(fā)頁面初始化數(shù)據(jù)的加載了
mViewModel.getPageData().observe(this, pagedList -> submitList(pagedList));

class MyItemKeyedDataSource extends ItemKeyedDataSource<GoodsModel>{
  public abstract void loadInitial(LoadInitialParams<Key> params,LoadInitialCallback<Value> callback){
     //頁面初始化數(shù)據(jù)加載
     callback.onResult(list)
  }
 public void loadAfter(@NonNull LoadParams<Key> params,LoadCallback<Value> callback){
   //向后分頁數(shù)據(jù)加載...
    callback.onResult(list)
 }
 public void loadBefore(LoadParams<Key> params,LoadCallback<Value> callback){
   //向前分頁數(shù)據(jù)加載...
   callback.onResult(list)
 }
}

WorkManager : 新一代后臺任務管理組件曹宴,功能比較強大,service能做的事情它都能做

支持周期性任務調度歉提、鏈式任務調度笛坦、豐富的任務約束條件、即便程序退出苔巨,依舊能保證任務的執(zhí)行

api "android.arch.work:work-runtime:1.0.1"


//#1.構建任務
class UploadFileWorker extends Worker{
   public Result doWork() {
     //執(zhí)行文件上傳的任務
     return Result.success()
   }
}

//#2.構建 執(zhí)行任務的request對象
OneTimeWorkRequest request = new OneTimeWorkRequest
      .Builder(UploadFileWorker.class)
      .build()
  
//#3.把任務加入調度隊列  
WorkContinuation workContinuation = WorkManager.getInstance(context).beginWith(request); 
workContinuation.then(workB).then(workC).enqueue()

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末版扩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子侄泽,更是在濱河造成了極大的恐慌礁芦,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件悼尾,死亡現(xiàn)場離奇詭異柿扣,居然都是意外死亡,警方通過查閱死者的電腦和手機闺魏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門未状,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人析桥,你說我怎么就攤上這事司草。” “怎么了烹骨?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵翻伺,是天一觀的道長。 經常有香客問我沮焕,道長吨岭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任峦树,我火速辦了婚禮辣辫,結果婚禮上旦事,老公的妹妹穿的比我還像新娘。我一直安慰自己急灭,他們只是感情好姐浮,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著葬馋,像睡著了一般卖鲤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上畴嘶,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天蛋逾,我揣著相機與錄音,去河邊找鬼窗悯。 笑死区匣,一個胖子當著我的面吹牛,可吹牛的內容都是我干的蒋院。 我是一名探鬼主播亏钩,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼欺旧!你這毒婦竟也來了姑丑?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤切端,失蹤者是張志新(化名)和其女友劉穎彻坛,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體踏枣,經...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡昌屉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了茵瀑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片间驮。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖马昨,靈堂內的尸體忽然破棺而出竞帽,到底是詐尸還是另有隱情,我是刑警寧澤鸿捧,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布屹篓,位于F島的核電站,受9級特大地震影響匙奴,放射性物質發(fā)生泄漏堆巧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谍肤。 院中可真熱鬧啦租,春花似錦、人聲如沸荒揣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽系任。三九已至恳蹲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赋除,已是汗流浹背阱缓。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留举农,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓敞嗡,卻偏偏與公主長得像颁糟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子喉悴,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內容