Skip to content

99.Migrate from v1.x.x

Kilnn edited this page Jan 26, 2023 · 16 revisions

1.升级到RxJava3

旧SDK基于RxJava2开发,新SDK基于RxJava3开发。

RxJava3对比RxJava2,更改了大量的包名(还有极少数的API接口)。如果要使用新SDK,APP必须要升级到RxJava3,这会导致APP内大量的类报错,需要重新导入RxJava3更改包名的类。 所以在升级到新SDK之前,提供一个旧SDK-RxJava3的版本,这样先完成RxJava3的升级。

这一步基本不会有啥的问题,就是比较繁琐,需要大量导入新的类。

去掉旧的libraryCore_v1.1.9.aar,改为libraryCore_rxjava3_v1.1.9.aar。依赖如下:

dependencies {
    //必须的aar文件和依赖库.
    implementation files('../aar/libraryCore_rxjava3_v1.1.9.aar')
    implementation "io.reactivex.rxjava3:rxjava:3.1.5"
    implementation  "io.reactivex.rxjava3:rxandroid:3.0.2"
    implementation "com.polidea.rxandroidble3:rxandroidble:1.17.2"

    //可选的. 用于OTA功能以及表盘、游戏、运动推送等功能。
    implementation files('../aar/libraryDfu_v1.0.5.aar')
    //可选的. 如果手环是Nordic芯片并且需要OTA等功能时,如果不确定手环是什么芯片,可以直接加上。
    implementation 'no.nordicsemi.android:dfu:1.10.3'
}

还有一些RxJava2相关的库,也要切换为RxJava3,这个根据自己APP内的使用情况。比如

implementation "androidx.room:room-rxjava3:2.4.3"
implementation "com.squareup.retrofit2:adapter-rxjava3:2.9.0"
implementation  "org.jetbrains.kotlinx:kotlinx-coroutines-rx3:1.6.4"

2.升级到新SDK

移除旧版本的依赖和aar包,改为如下的方式:

dependencies {
    //必须的aar文件和依赖库.
    implementation files('../aar/libraryCore_v2.0.0-alpha02.00.aar')
    implementation files('../aar/libraryProtocol2_v2.0.0-alpha02.00.aar')
    implementation "androidx.core:core-ktx:1.9.0"
    implementation "androidx.annotation:annotation:1.5.0"
    implementation "com.jakewharton.timber:timber:5.0.1"
    implementation "io.reactivex.rxjava3:rxjava:3.1.5"
    implementation  "io.reactivex.rxjava3:rxandroid:3.0.2"
    implementation "com.polidea.rxandroidble3:rxandroidble:1.17.2"

    //可选的. 提供了1.x.x兼容的一些API,这样迁移的时候可以尽量减少接口的变更。(如果是新开发的话,那完全不需要加). 
    implementation files('../aar/libraryCompat2_v2.0.0-alpha02.00.aar')

    //可选的. 用于OTA功能以及表盘、游戏、运动推送等功能。
    implementation files('../aar/libraryDfu8762C_v2.0.0-alpha02.00.aar')
    //可选的. 如果手环是Nordic芯片并且需要OTA等功能时,如果不确定手环是什么芯片,可以直接加上。
    implementation 'no.nordicsemi.android:dfu:2.2.2'
    //可选的(建议加上). 用于OTA功能时下载文件。如果不加的话,默认使用URLConnection下载。 
    implementation 'com.squareup.okhttp3:okhttp:4.10.0'
    //可选的. 如果需要内置的音乐控制功能,需要加上。
    implementation 'androidx.media:media:1.6.0'
}

2.1 初始化

WristbandApplication类不在具有初始化功能,使用以下方式初始化。

import android.app.Application
import android.content.Context
import androidx.annotation.MainThread
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ProcessLifecycleOwner
import com.htsmart.wristband.app.exception.PlatformAuthErrorException
import com.polidea.rxandroidble3.LogConstants
import com.polidea.rxandroidble3.LogOptions
import com.polidea.rxandroidble3.RxBleClient
import com.topstep.fitcloud.sdk.util.FcRxJavaPluginsErrorHandler
import com.topstep.fitcloud.sdk.v2.FcSDK
import io.reactivex.rxjava3.plugins.RxJavaPlugins
import timber.log.Timber
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

@MainThread
fun fitCloudSDKInit(application: Application) {
    //*Note**:1.配置Log
    //"FitCloudSDK"内使用Timber作为日志输出,需要需要初始化Timber
    Timber.plant(Timber.DebugTree())

    //"FitCloudSDK"中的蓝牙功能基于"RxAndroidBLE"开源库. 所以同样需要配置"RxAndroidBLE"的Log输出
    RxBleClient.updateLogOptions(
        LogOptions.Builder()
            .setShouldLogAttributeValues(BuildConfig.DEBUG)
            .setShouldLogScannedPeripherals(false)
            .setMacAddressLogSetting(if (BuildConfig.DEBUG) LogConstants.MAC_ADDRESS_FULL else LogConstants.NONE)
            .setUuidsLogSetting(if (BuildConfig.DEBUG) LogConstants.UUIDS_FULL else LogConstants.NONE)
            .setLogLevel(if (BuildConfig.DEBUG) LogConstants.DEBUG else LogConstants.INFO)
            .setLogger { level, tag, msg ->
                Timber.tag(tag).log(level, msg)
            }
            .build()
    )

    //**Note**:2.初始化"FitCloudSDK"
    //在使用"FitCloudSDK"任何功能之前,必须先初始化
    //在这个示例中,使用Kotlin代理的功能来维持一个单例.
    //如果你使用其他方式,你可以自己创建一个[FcSDK]的对象,并维持这个单例。
    application.fcSDK

    //**Note**:3.UI进程的状态
    //"FitCloudSDK"部分功能需要当前UI进程的前后台状态.你必须正确处理此状态
    //在这个示例中,使用[ProcessLifecycleOwner]来设置前后台状态。你也可以用其他的方法,比如[ActivityLifecycleCallbacks]
    ProcessLifecycleOwner.get().lifecycle.addObserver(object : DefaultLifecycleObserver {
        override fun onStart(owner: LifecycleOwner) {
            application.fcSDK.isForeground = true
        }

        override fun onStop(owner: LifecycleOwner) {
            application.fcSDK.isForeground = false
        }
    })

    //**Note**:4.RxJavaPlugins.setErrorHandler
    //因为"FitCloudSDK"基于RxJava, 需要处理一些无法分发的已知异常,以避免应用程序崩溃。
    val ignoreErrors = HashSet<Class<out Throwable>>()
    ignoreErrors.add(PlatformAuthErrorException::class.java)//你自己的APP中需要忽略的异常(根据你自己APP的情况,可能没有)
    ignoreErrors.addAll(FcSDK.rxJavaPluginsIgnoreExceptions())//SDK中需要忽略的异常
    RxJavaPlugins.setErrorHandler(FcRxJavaPluginsErrorHandler(ignoreErrors))

    //必须主线程初始化connector
    application.fcSDK.connector
}

//Keep the FcSDK singleton and call it anywhere using context
val Context.fcSDK: FcSDK by FcSDKSingletonDelegate()

internal class FcSDKSingletonDelegate : ReadOnlyProperty<Context, FcSDK> {
    private val lock = Any()

    @Volatile
    private var instance: FcSDK? = null
    override fun getValue(thisRef: Context, property: KProperty<*>): FcSDK {
        return instance ?: synchronized(lock) {
            if (instance == null) {
                instance = FcSDK
                    .Builder(thisRef.applicationContext as Application)
                    .setTestStrictMode(BuildConfig.DEBUG)
                    .build()
            }
            instance!!
        }
    }
}

在你的Application.onCreate()方法中,调用fitCloudSDKInit方法,然后就可以使用WristbandApplication.getWristbandManager()获取WristbandManager对象了。

2.2 获取RxBleClient

WristbandApplication不在提供getRxBleClient方法,请使用FcSDK.getRxBleClient()获取。

2.3 SleepCalculateHelperICalculateSleepItem变更

包名变更,重新导入即可。

2.4 SyncDataRaw.getConfig()返回类型变更为FcDeviceInfo

请使用此新接口用于判断设备是否支持某个功能。比如:

if (syncDataRaw.getConfig().isSupportFeature(FcDeviceInfo.Feature.STEP_EXTRA)) {
    items = DeviceDataUtils.mapStep(datas, device);
} else {
    items = DeviceDataUtils.mapStep(datas, device, mStepLength, mWeight);
}

2.5.DialDrawer.Shape变更

使用FcShape代替

2.6 DialDrawerDialViewDialWriter等变更。

包名变更,重新导入即可。

DialDrawer.ScaleType.fromId方法改为使用DialDrawer.ScaleType.fromOrdinal DialDrawer.Position.fromId方法改为使用DialDrawer.Position.fromOrdinal

DialViewxml属性dv_scale_type变更为dv_background_scale_type

删除了DialViewEngine类,DialView不在提供setEngine方法,也不能直接使用Uri加载背景图和样式图。请自己加载图片,然后设置给DialView。比如,用Glide加载图片:

import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.topstep.fitcloud.sdk.v2.utils.dial.DialView

object DialBitmapUtil {
    fun glideLoadDialBackground(context: Context, dialView: DialView, uri: Any) {
        Glide.with(context)
            .asBitmap()
            .load(uri)
            .into(object : CustomTarget<Bitmap?>() {
                override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap?>?) {
                    dialView.backgroundBitmap = resource
                }

                override fun onLoadCleared(placeholder: Drawable?) {
                    dialView.backgroundBitmap = null
                }
            })
    }

    fun glideLoadDialStyle(context: Context, dialView: DialView, uri: Any, styleBaseOnWidth: Int) {
        Glide.with(context)
            .asBitmap()
            .load(uri)
            .into(object : CustomTarget<Bitmap?>() {
                override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap?>?) {
                    dialView.setStyleBitmap(resource, styleBaseOnWidth)
                }

                override fun onLoadCleared(placeholder: Drawable?) {
                    dialView.setStyleBitmap(null, styleBaseOnWidth)
                }
            })
    }
}

2.7 DfuManager变更

构造方法变更:

dfuManager = DfuManager(fcSDK)

升级方法变更,使用DfuManager新的upgrade方法:

public void upgrade(FcDfuManager.DfuType dfuType, Uri uri, byte binFlag)

Clone this wiki locally