Skip to content

2.开发实例

Ryens edited this page May 5, 2024 · 6 revisions

接下来通过演示今热的基本开发流程加深理解

1.初始化工程

新建一个Android工程,创建git版本控制后,运行指令

git submodule add https://github.com/RyensX/MediaBoxPlugin.git submodules/MediaBoxPlugin

目前插件API还没有打包上传到Maven,因此建议通过以上submodule的方式引用。

另外目前还提供了更高一层封装的插件基础框架可选使用,点击这里可查看

然后在settings.gradle.kts(settings.gradle)底部添加代码导入模块

val pluginApi = ":MediaBoxPluginApi"
include(pluginApi)
project(pluginApi).projectDir = File("./submodules/MediaBoxPlugin/pluginApi")

注意:这是kts,建议把默认的settings.gradle删除新建settings.gradle.kts

完整settings.gradle.kts代码

pluginManagement {
    repositories {
        gradlePluginPortal()
        google()
        mavenCentral()
    }
}
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
    }
}
rootProject.name = "TodayHot"
include(":app")

val pluginApi = ":MediaBoxPluginApi"
include(pluginApi)
project(pluginApi).projectDir = File("./submodules/MediaBoxPlugin/pluginApi")

2.注册插件

在任意一个包下新建一个类,继承IPluginFactory

package com.su.todayhot.plugin

import com.su.mediabox.pluginapi.IPluginFactory
import com.su.mediabox.pluginapi.action.Action
import com.su.mediabox.pluginapi.action.CustomPageAction
import com.su.mediabox.pluginapi.action.HomeAction
import com.su.mediabox.pluginapi.components.IBasePageDataComponent
import com.su.todayhot.plugin.components.HotPageComponent

class PluginFactory : IPluginFactory() {

    //今热没有具体host所以留空
    override val host: String = ""

    //自定义了初始化Action,具体看IPluginFactory的文档注释
    override val initAction: Action
        get() = CustomPageAction.obtain(HotPageComponent::class.java)

    //自定义了页面数据组件
    @Suppress("UNCHECKED_CAST")
    override fun <T : IBasePageDataComponent> createComponent(clazz: Class<T>): T? {
        return HotPageComponent() as? T?
    }

}

然后打开AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.su.todayhot">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true">

        <!--第一步:每个插件必须注册这里才能被识别为插件-->
        <!--name固定media_plugin_api_impl-->
        <!--value填写上面写的类完整包名-->
        <meta-data
            android:name="media_plugin_api_impl"
            android:value="com.su.todayhot.plugin.PluginFactory" />

        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <!--第二步:可选,方便调试-->
                <!--name固定media_plugin_debug-->
                <action android:name="media_plugin_debug" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

这里的<action android:name="media_plugin_debug" />为可选项,目的是为了让媒体盒子能直接检测到外部以apk方式安装到系统上的插件以方便调试,注意:只有debug版的媒体盒子才能检测到外部插件

有一点需要注意的是,由于Android的问题,如果你在开发插件时不更新versionCode或versionName覆盖安装的话内部apk是不会更新的,这就导致你会发现明明改了代码但在媒体盒子中启动后没效果。所以最简单办法是直接卸载重装(直接实机调试),媒体盒子可以实时检测到插件变动并自动更新(若插件已在运行则需要重开插件)。

3.编写页面数据组件

今热只有一个页面数据组件,是一个自定义页面数据组件HotPageComponent,复杂一些。最简单是使用默认的IHomePageDataComponent,继承它写一个页面数据组件,启动插件时默认启动IHomePageDataComponent。

class HomePageDataComponent : IHomePageDataComponent {

    override suspend fun getData(page: Int): List<BaseData>? {
        val data=mutableListOf<BaseData>()
        data.add(SimpleTextData("一个占满整行的文本"))
        return data;
    }

}

可以去参考插件仓库的各个插件的实现,比如樱花动漫的,也可以直接拷贝整个实现然后根据自己需要改。

写好后在2实现的PluginFactory里返回实例

package com.su.todayhot.plugin

import com.su.mediabox.pluginapi.IPluginFactory
import com.su.mediabox.pluginapi.action.Action
import com.su.mediabox.pluginapi.action.CustomPageAction
import com.su.mediabox.pluginapi.action.HomeAction
import com.su.mediabox.pluginapi.components.IBasePageDataComponent
import com.su.todayhot.plugin.components.HotPageComponent

class PluginFactory : IPluginFactory() {

    @Suppress("UNCHECKED_CAST")
    override fun <T : IBasePageDataComponent> createComponent(clazz: Class<T>): T? {
        return HomePageDataComponent() as? T?
    }

}

如果实现了很多个不同类型组件需要使用,可以参考:

class PluginFactory : IPluginFactory() {

    override val host: String = Const.host

    override fun <T : IBasePageDataComponent> createComponent(clazz: Class<T>) = when (clazz) {
        IVideoPlayPageDataComponent::class.java -> VideoPlayPageDataComponent()
        IMediaSearchPageDataComponent::class.java -> MediaSearchPageDataComponent()
        IMediaDetailPageDataComponent::class.java -> MediaDetailPageDataComponent()
        IMediaClassifyPageDataComponent::class.java -> MediaClassifyPageDataComponent()
        IHomePageDataComponent::class.java -> HomePageDataComponent()
        //自定义页面,需要使用具体类而不是它的基类(接口)
        RankPageDataComponent::class.java -> RankPageDataComponent()
        UpdateTablePageDataComponent::class.java -> UpdateTablePageDataComponent()
        else -> null
    } as? T

}

4.编译安装

像平时调试安装apk那样做即可,媒体盒子会自动检测(见上面提示,有debug action且媒体盒子是测试版才能检测)。

正式发布时想普通Android App那样打包apk即可,但推荐把后缀名改为mpp,如插件.mpp

更多使用方法可以看API源码,里面有详细的文档注释。

另外欢迎提交插件到官方插件仓库

Clone this wiki locally