您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)Paging庫怎么在Android 中使用,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。
添加分頁依賴
按照如下代碼添加依賴:
dependencies { def paging_version = "1.0.0" implementation "android.arch.paging:runtime:$paging_version" // alternatively - without Android dependencies for testing testImplementation "android.arch.paging:common:$paging_version" // optional - RxJava support, currently in release candidate implementation "android.arch.paging:rxjava2:1.0.0-rc1" }
備注: 分頁包幫助開發(fā)者在UI的列表容器中順暢地展示數(shù)據(jù), 而不管是使用設(shè)備內(nèi)部的數(shù)據(jù)庫還是從應(yīng)用后端拉取數(shù)據(jù).
庫架構(gòu)
分頁庫的核心構(gòu)件是PagedList類, 它是一個(gè)集合, 用于異步加載應(yīng)用數(shù)據(jù)塊或者數(shù)據(jù)頁. 該類在應(yīng)用的其它架構(gòu)之間充當(dāng)中介.
Data
每一個(gè)PagedList實(shí)例從DataSource中加載最新的應(yīng)用數(shù)據(jù). 數(shù)據(jù)從應(yīng)用后端或者數(shù)據(jù)庫流入PagedList對象. 分頁包支持多樣的應(yīng)用架構(gòu), 包括脫機(jī)數(shù)據(jù)庫和與后臺服務(wù)器通訊的數(shù)據(jù)庫.
UI
PagedList類通過PagedListAdapter加載數(shù)據(jù)項(xiàng)到RecyclerView里面. 在加載數(shù)據(jù)的時(shí)候, 這些類協(xié)同工作, 拉取數(shù)據(jù)并展示內(nèi)容, 包括預(yù)取看不見的內(nèi)容并在內(nèi)容改變時(shí)加載動(dòng)畫.
支持不同的數(shù)據(jù)架構(gòu)
分頁包支持應(yīng)用架構(gòu), 包括應(yīng)用拉取數(shù)據(jù)的地方是從后臺服務(wù)器, 還是本機(jī)數(shù)據(jù)庫, 還是兩者的結(jié)合.
只有網(wǎng)絡(luò)
要展示后臺數(shù)據(jù), 需要使用Retrofit的同步版本, 加載信息到自定義的DataSource對象中.
備注: 分頁包的DataSource對象并沒有提供任何錯(cuò)誤處理機(jī)制, 因?yàn)椴煌膽?yīng)用需要用不同的方式處理和展示UI錯(cuò)誤. 如果錯(cuò)誤發(fā)生了, 順從結(jié)果的回調(diào), 然后稍后重試.
只有數(shù)據(jù)庫
要設(shè)置RecyclerView觀測本地存儲, 偏向于使用Room持久化庫. 用這種方式, 無論任何時(shí)候數(shù)據(jù)庫數(shù)據(jù)插入或者修改, 這些改變會自動(dòng)地在負(fù)責(zé)展示這些數(shù)據(jù)的RecyclerView展示出來.
網(wǎng)絡(luò)+數(shù)據(jù)庫
在開始觀測數(shù)據(jù)庫之后, 你能夠通過使用PagedList.BoundaryCallback來監(jiān)聽數(shù)據(jù)庫什么時(shí)候過期. 之后, 你可能從網(wǎng)絡(luò)拉取更多的數(shù)據(jù), 并把它們插入到數(shù)據(jù)庫中. 如果UI正在展示數(shù)據(jù)庫, 以上就是你所需要做的全部.
下面的代碼片斷展示了BoundaryCallback的使用實(shí)例:
class ConcertViewModel { fun search(query: String): ConcertSearchResult { val boundaryCallback = ConcertBoundaryCallback(query, myService, myCache) // Error-handling not shown in this snippet. val networkErrors = boundaryCallback.networkErrors } } class ConcertBoundaryCallback( private val query: String, private val service: MyService, private val cache: MyLocalCache ) : PagedList.BoundaryCallback<Concert>() { override fun onZeroItemsLoaded() { requestAndSaveData(query) } override fun onItemAtEndLoaded(itemAtEnd: Concert) { requestAndSaveData(query) } }
處理網(wǎng)絡(luò)錯(cuò)誤
在使用網(wǎng)絡(luò)拉取或者分頁的數(shù)據(jù), 而這些數(shù)據(jù)正在使用分頁包展示的時(shí)候, 不總是把網(wǎng)絡(luò)分為要么"可用"要么"不可能"是很重要的, 因?yàn)樵S多連接是間歇性或者成片的:
特定的服務(wù)器可能不能響應(yīng)網(wǎng)絡(luò)請求;
設(shè)備可能聯(lián)接了慢的或者弱的網(wǎng)絡(luò);
應(yīng)用應(yīng)該檢查每一個(gè)請求是否成功, 并且在網(wǎng)絡(luò)不可用的情形下, 盡可能快地恢復(fù). 比如, 你可以為用戶提供一個(gè)"重試"按鈕, 如果數(shù)據(jù)沒有刷新成功的話. 如果在數(shù)據(jù)分頁期間發(fā)生錯(cuò)誤, 最好自動(dòng)地重新分頁請求.
更新已有應(yīng)用
如果應(yīng)用已經(jīng)從網(wǎng)絡(luò)或者數(shù)據(jù)庫消費(fèi)數(shù)據(jù), 很大可能可以直接升級到分頁庫提供的功能.
自定義分頁解決方案
如果你使用了自定義功能加載數(shù)據(jù)源中的小的數(shù)據(jù)集, 你可以使用PagedList類取代這個(gè)邏輯. PagedList類實(shí)例提供了內(nèi)建的連接, 到通用的數(shù)據(jù)源. 這些實(shí)例也提供了在應(yīng)用中引用的RecyclerView的適配器.
使用列表而非分頁加載的數(shù)據(jù)
如果你使用內(nèi)存里的列表作為UI適配器的后備數(shù)據(jù)結(jié)構(gòu), 考慮使用PagedList類觀測數(shù)據(jù)更新, 如果列表中數(shù)據(jù)項(xiàng)變得很多的話. PagedList實(shí)例既可以使用LiveData<PagedList>也可以使用Observable<List>對UI傳遞數(shù)據(jù)更新, 同時(shí)最小化了加載時(shí)間和內(nèi)存使用. 然而, 應(yīng)用中使用PagedList對象代替List并不要求對UI結(jié)構(gòu)和數(shù)據(jù)更新邏輯作任何改變.
使用CursorAdapter將數(shù)據(jù)cursor與列表視圖聯(lián)系起來
應(yīng)用也許會使用CursorAdapter將數(shù)據(jù)從Cursor跟ListView連接起來. 在這種情況下, 通常需要從ListView遷移到RecyclerView, 然后使用Room或者PositionalDataSource構(gòu)件代替Cursor, 當(dāng)然, 這主要依據(jù)于Cursor實(shí)例能否訪問SQLite數(shù)據(jù)庫.
在一些情況下, 比如使用Spinner實(shí)例的時(shí)候, 你僅僅提供了Adapter本身. 然后一個(gè)庫使用了加載進(jìn)adapter中的數(shù)據(jù), 并展示了數(shù)據(jù). 在這些情況下, 把a(bǔ)dapter數(shù)據(jù)類型轉(zhuǎn)化為LiveData<PagedList>, 之后在嘗試使用將這些數(shù)據(jù)項(xiàng)在UI中填充起來之前, 將這個(gè)列表在ArrayAdapter對象中包裹起來.
使用AsyncListUtil異步加載內(nèi)容
如果你在使用AsyncListUtil對象異步地加載和展示分組信息的話, 分頁包將會使得加載數(shù)據(jù)更加方便:
數(shù)據(jù)并不需要定位. 分頁包讓你直接從后臺使用網(wǎng)絡(luò)提供的鍵加載數(shù)據(jù).
數(shù)據(jù)量太大. 使用分頁包可以將數(shù)據(jù)加載分頁直到?jīng)]有任何數(shù)據(jù)留下.
更方便地觀測數(shù)據(jù). 分頁包能夠展示應(yīng)用在可觀測數(shù)據(jù)結(jié)構(gòu)中持有的ViewModel.
數(shù)據(jù)庫例子
使用LiveData觀測分頁數(shù)據(jù)
下面的示例代碼展示了所有一起工作的碎片. 當(dāng)演唱會事件在數(shù)據(jù)庫中添加, 刪除或者修改的修改的時(shí)候, RecyclerView中的內(nèi)容自動(dòng)且高效地更新:
@Dao interface ConcertDao { // The Integer type parameter tells Room to use a PositionalDataSource // object, with position-based loading under the hood. @Query("SELECT * FROM user ORDER BY concert DESC") fun concertsByDate(): DataSource.Factory<Int, Concert> } class MyViewModel(concertDao: ConcertDao) : ViewModel() { val concertList: LiveData<PagedList<Concert>> = LivePagedListBuilder( concertDao.concertsByDate(), /* page size */ 20 ).build() } class MyActivity : AppCompatActivity() { public override fun onCreate(savedState: Bundle?) { super.onCreate(savedState) val viewModel = ViewModelProviders.of(this) .get(MyViewModel::class.java!!) val recyclerView = findViewById(R.id.concert_list) val adapter = ConcertAdapter() viewModel.concertList.observe(this, { pagedList -> adapter.submitList(pagedList) }) recyclerView.setAdapter(adapter) } } class ConcertAdapter() : PagedListAdapter<Concert, ConcertViewHolder>(DIFF_CALLBACK) { fun onBindViewHolder(holder: ConcertViewHolder, position: Int) { val concert = getItem(position) if (concert != null) { holder.bindTo(concert) } else { // Null defines a placeholder item - PagedListAdapter automatically // invalidates this row when the actual object is loaded from the // database. holder.clear() } } companion object { private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Concert>() { // Concert details may have changed if reloaded from the database, // but ID is fixed. override fun areItemsTheSame(oldConcert: Concert, newConcert: Concert): Boolean = oldConcert.id == newConcert.id override fun areContentsTheSame(oldConcert: Concert, newConcert: Concert): Boolean = oldConcert == newConcert } } }
使用RxJava2觀測分頁數(shù)據(jù)
如果你偏愛使用RxJava2而非LiveData, 那么你可以創(chuàng)建Observable或者Flowable對象:
class MyViewModel(concertDao: ConcertDao) : ViewModel() { val concertList: Flowable<PagedList<Concert>> = RxPagedListBuilder( concertDao.concertsByDate(), /* page size */ 50 ).buildFlowable(BackpressureStrategy.LATEST) }
之后你可以按照如下代碼開始和停止觀測數(shù)據(jù):
class MyActivity : AppCompatActivity() { private lateinit var adapter: ConcertAdapter<Concert> private lateinit var viewModel: MyViewModel private val disposable = CompositeDisposable() public override fun onCreate(savedState: Bundle?) { super.onCreate(savedState) val recyclerView = findViewById(R.id.concert_list) viewModel = ViewModelProviders.of(this).get(MyViewModel::class.java!!) adapter = ConcertAdapter() recyclerView.setAdapter(adapter) } override fun onStart() { super.onStart() disposable.add(viewModel.concertList.subscribe({ flowableList -> adapter.submitList(flowableList) })) } override fun onStop() { super.onStop() disposable.clear() } }
基于RxJava2解決方案的ConcertDao和ConcertAdapter代碼, 和基于LiveData解決方案的代碼是一樣的.
UI構(gòu)件及其出發(fā)點(diǎn)
將UI和視圖模型聯(lián)接起來
你可以按照如下方式, 將LiveData<PagedList>實(shí)例跟PagedListAdapter聯(lián)系起來:
private val adapter = ConcertPagedListAdapter() private lateinit var viewModel: ConcertViewModel override fun onCreate(savedInstanceState: Bundle?) { viewModel = ViewModelProviders.of(this) .get(ConcertViewModel::class.java) viewModel.concerts.observe(this, adapter::submitList) }
當(dāng)數(shù)據(jù)源提供一個(gè)新PagedList實(shí)例的時(shí)候, activity會將這些對象改善給adapter. PagedListAdapter實(shí)現(xiàn), 定義了更新如何計(jì)算, 自動(dòng)地處理分頁和列表不同. 由此, 你的ViewHolder只需要綁定到特定的提供項(xiàng):
class ConcertPagedListAdapter() : PagedListAdapter<Concert, ConcertViewHolder>( object : DiffUtil.ItemCallback<Concert>() { // The ID property identifies when items are the same. override fun areItemsTheSame(oldItem: Concert, newItem: Concert) = oldItem.id = newItem.id // Use the "==" operator (or Object.equals() in Java-based code) to know // when an item's content changes. Implement equals(), or write custom // data comparison logic here. override fun areContentsTheSame(oldItem: Concert, newItem: Concert) = oldItem.name == newItem.name && oldItem.date == newItem.date } ) { override fun onBindViewHolder(holder: ConcertViewHolder, position: Int) { val concert: Concert? = getItem(position) // Note that "concert" is a placeholder if it's null holder.bind(concert) } }
PagedListAdapter使用PagedList.Callback對象處理分頁加載事件. 當(dāng)用戶滑動(dòng)時(shí), PagedListAdapter調(diào)用PagedList.loadAround()方法將從DataSource中拉聚攏數(shù)據(jù)項(xiàng)提示提供給基本的PagedList.
備注: PageList是內(nèi)容不可變的. 這意味著, 盡管新內(nèi)容能夠被加載到PagedList實(shí)例中, 但已加載項(xiàng)一旦加載完成便不能發(fā)生改變. 由此, 如果PagedList中的內(nèi)容發(fā)生改變, PagedListAdapter對象將會接收到一個(gè)包含已更新信息的全新的PagedList.
實(shí)現(xiàn)diffing回調(diào)
先前的代碼展示了areContentsTheSame()的手動(dòng)實(shí)現(xiàn), 它比較了對象的相關(guān)的域. 你也可以使用Java中的Object.equals()方法或者Kotlin中的==操作符. 但是要確保要么實(shí)現(xiàn)了對象中的equals()方法或者使用了kotlin中的數(shù)據(jù)對象.
使用不同的adapter類型進(jìn)行diffing
如果你選擇不從PagedListAdapter繼承--比如你在使用一個(gè)提供了自己的adapter的庫的時(shí)候--你依然可以通過直接使用AsyncPagedListDiffer對象使用分頁包adapter的diffing功能.
在UI中提供占位符
在應(yīng)用完成拉取數(shù)據(jù)之前, 如果你想U(xiǎn)I展示一個(gè)列表, 你可以向用戶展示占位符列表項(xiàng). RecyclerView通過將列表項(xiàng)臨時(shí)地設(shè)置為null來處理這個(gè)情況.
備注: 默認(rèn)情況下, 分頁包開啟了占位符行為.
占位符有如下好處:
支持scrollbar. PagedList向PagedListAdapter提供了大量的列表項(xiàng). 這個(gè)信息允許adapter繪制一個(gè)表示列表已滿的scrollbar. 當(dāng)新的頁加載時(shí), scrollbar并不會跳動(dòng), 因?yàn)榱斜硎遣⒉粵]有改變它的size.
不需要"正在加載"旋轉(zhuǎn)指針. 因?yàn)榱斜泶笮∫阎? 沒必要提醒用戶有更多的數(shù)據(jù)項(xiàng)正在加載. 占位符本身表達(dá)了這個(gè)信息.
在添加占位符的支持之前, 請牢記以下先置條件:
要求集合中數(shù)據(jù)可數(shù). 來自Room持久化庫的DataSource實(shí)例能夠高效地計(jì)算數(shù)據(jù)項(xiàng). 然而, 如果你在用自定義本地存儲方案或者只有網(wǎng)絡(luò)的數(shù)據(jù)架構(gòu), 想了解數(shù)據(jù)集中有多少數(shù)據(jù)項(xiàng)可能代價(jià)很高, 甚至不可能.
要求adapter負(fù)責(zé)未加載數(shù)據(jù)項(xiàng). 你正在使用的adapter或者展示機(jī)制來準(zhǔn)備填充列表, 需要處理null列表項(xiàng). 比如, 當(dāng)將數(shù)據(jù)綁定到ViewHolder的時(shí)候, 你需要提供默認(rèn)值表示未加載數(shù)據(jù).
要求數(shù)據(jù)相同數(shù)量的item view. 如果列表項(xiàng)數(shù)目能夠基于內(nèi)容發(fā)生改變, 比如, 社交網(wǎng)絡(luò)更新, 交叉淡入淡出看起來并不好. 在這種情況下, 強(qiáng)烈推薦禁掉占位符.
數(shù)據(jù)構(gòu)件及其出發(fā)點(diǎn)
構(gòu)建可觀測列表
通常情況下, UI代碼觀測LiveData<PagedList>對象(或者, 如果你在使用RxJava2, 是Flowable<PagedList>/Observable<PagedList>對象), 這個(gè)對象存在于應(yīng)用的ViewModel中. 這個(gè)可觀測對象形成了應(yīng)用列表數(shù)據(jù)內(nèi)容和展示的連接.
要?jiǎng)?chuàng)建這么一個(gè)可觀測PagedList對象, 需要將DataSource.Factory實(shí)例傳給LivePageListBuilder/RxPagedListBuilder對象. 一個(gè)DataSource對象對單個(gè)PagedList加載分頁. 這個(gè)工廠類為內(nèi)容更新創(chuàng)建PagedList實(shí)例, 比如數(shù)據(jù)庫表驗(yàn)證, 網(wǎng)絡(luò)刷新等. Room持久化庫能夠提供DataSource.Factory, 或者自定義.
如下代碼展示了如何在應(yīng)用的ViewModel類中使用Room的DataSource.Factory構(gòu)建能力創(chuàng)建新的LiveData<PagedaList>實(shí)例:
ConcertDao.kt:
interface ConcertDao { // The Integer type parameter tells Room to use a PositionalDataSource // object, with position-based loading under the hood. @Query("SELECT * FROM concerts ORDER BY date DESC") public abstract DataSource.Factory<Integer, Concert> concertsByDate() }
ConcertViewModel.kt:
// The Integer type argument corresponds to a PositionalDataSource object. val myConcertDataSource : DataSource.Factory<Integer, Concert> = concertDao.concertsByDate() val myPagedList = LivePagedListBuilder(myConcertDataSource, /* page size */ 20) .build()
定義分頁配置
要想為復(fù)雜情形更深入地配置LiveData<PagedList>, 你也可以定義自己的分頁配置. 尤其是, 你可以定義如下屬性:
頁大小: 每一頁的數(shù)據(jù)量.
預(yù)取距離: 給定UI中最后可見項(xiàng), 超過該項(xiàng)之后多少項(xiàng), 分頁包要嘗試提前提取數(shù)據(jù). 這個(gè)值應(yīng)該比page size大幾倍.
占位符展示: 決定了UI是否會為還沒有完成加載的數(shù)據(jù)項(xiàng)展示占位符.
如果你想要對分布包從數(shù)據(jù)庫加載中設(shè)置更多的控件, 要像下面的代碼一樣, 傳遞自定義的Executor對象給LivePagedListBuilder:
EventViewModel.kt:
val myPagingConfig = PagedList.Config.Builder() .setPageSize(50) .setPrefetchDistance(150) .setEnablePlaceholders(true) .build() // The Integer type argument corresponds to a PositionalDataSource object. val myConcertDataSource : DataSource.Factory<Integer, Concert> = concertDao.concertsByDate() val myPagedList = LivePagedListBuilder(myConcertDataSource, myPagingConfig) .setFetchExecutor(myExecutor) .build()
選擇正確的數(shù)據(jù)源類型
連接更最好地處理源數(shù)據(jù)結(jié)構(gòu)的數(shù)據(jù)源很重要:
如果加載的頁嵌套了之前/之后頁的key的話, 使用PageKeyDataSource. 比如, 比如你正在從網(wǎng)絡(luò)中拉取社交媒體博客, 你也許需要傳遞從一次加載向下一次加載的nextPage token.
如果需要使用每N項(xiàng)數(shù)據(jù)項(xiàng)的數(shù)據(jù)拉取每N+1項(xiàng)的話, 使用ItemKeyedDataSource. 比如, 你在為一個(gè)討論型應(yīng)用拉取螺紋評論, 你可能需要傳遞最后一條評論的ID來獲取下一條評論的內(nèi)容.
如果你需要從數(shù)據(jù)商店中的任意位置拉取分頁數(shù)據(jù)的話, 使用PositionalDataSource. 這個(gè)類支持請求任意位置開始的數(shù)據(jù)集. 比如, 請求也許返回從位置1200開始的20條數(shù)據(jù).
通知數(shù)據(jù)非法
在使用分頁包時(shí), 在表或者行數(shù)據(jù)變得陳腐時(shí), 取決于數(shù)據(jù)層來通知應(yīng)用的其它層. 要想這么做的話, 需要從DataSource類中調(diào)用invalidate()方法.
備注: UI也可以使用"滑動(dòng)刷新"模式來觸發(fā)數(shù)據(jù)非法功能.
構(gòu)建自己的數(shù)據(jù)源
如果你使用了自定義的數(shù)據(jù)解決方案, 或者直接從網(wǎng)絡(luò)加載數(shù)據(jù), 你可以實(shí)現(xiàn)一個(gè)DataSource子類. 下面的代碼展示了數(shù)據(jù)源從給定的concert起始時(shí)間切斷:
class ConcertTimeDataSource(private val concertStartTime: Date) : ItemKeyedDataSource<Date, Concert>() { override fun getKey(item: Concert) = item.startTime override fun loadInitial( params: LoadInitialParams<Date>, callback: LoadInitialCallback<Concert>) { val items = fetchItems(concertStartTime, params.requestedLoadSize) callback.onResult(items) } override fun loadAfter( params: LoadParams<Date>, callback: LoadCallback<Concert>) { val items = fetchItemsAfter( date = params.key, limit = params.requestedLoadSize) callback.onResult(items) } }
通過創(chuàng)建真實(shí)的DataSource.Factory子類, 你之后能夠加載自定義的數(shù)據(jù)到PagedList對象. 下面的代碼展示了如何創(chuàng)建在之前代碼中定義的自定義數(shù)據(jù)源:
class ConcertTimeDataSourceFactory(private val concertStartTime: Date) : DataSource.Factory<Date, Concert>() { val sourceLiveData = MutableLiveData<ConcertTimeDataSource>() override fun create(): DataSource<Date, Concert> { val source = ConcertTimeDataSource(concertStartTime) sourceLiveData.postValue(source) return source } }
考慮內(nèi)容更新
當(dāng)你構(gòu)建可觀測PagedList對象的時(shí)候, 考慮一下內(nèi)容是如何更新的. 如果你直接從Room數(shù)據(jù)庫中加載數(shù)據(jù), 更新會自動(dòng)地推送到UI上面.
如果你在使用分頁的網(wǎng)絡(luò)API, 通常你會有用戶交互, 比如"滑動(dòng)刷新", 把它作為信號去驗(yàn)證當(dāng)前DataSource非法并請求一個(gè)新的. 這個(gè)行為出行在下面的代碼中:
class ConcertActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { ... concertViewModel.refreshState.observe(this, Observer { swipeRefreshLayout.isRefreshing = it == NetworkState.LOADING }) swipeRefreshLayout.setOnRefreshListener { concertViewModel.invalidateDataSource() } } }
提供數(shù)據(jù)表現(xiàn)之間的映射
對于DataSource加載的數(shù)據(jù), 分頁包支持基于數(shù)據(jù)項(xiàng)和基于頁的轉(zhuǎn)換.
下面的代碼中, concert名和日期的聯(lián)合被映射成包含姓名和日期的字符串:
class ConcertViewModel : ViewModel() { val concertDescriptions : LiveData<PagedList<String>> init { val factory = database.allConcertsFactory() .map { concert -> concert.name + " - " + concert.date } concerts = LivePagedListBuilder(factory, 30).build() } } }
如果在數(shù)據(jù)加載之后, 想要包裹, 轉(zhuǎn)換或者準(zhǔn)備item, 這將非常有用. 因?yàn)檫@個(gè)工作是在獲取執(zhí)行器中完成的, 你可以在其中執(zhí)行花銷巨大的工作, 比如, 從硬盤中讀取, 查詢數(shù)據(jù)庫等.
關(guān)于Paging庫怎么在Android 中使用就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。