最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android手游SDK組件化開發(fā)詳細(xì)實戰(zhàn)指南

 更新時間:2026年03月10日 09:41:44   作者:xq9527  
這篇文章主要介紹了Android手游SDK組件化開發(fā)的相關(guān)資料,采用組件化架構(gòu)將功能模塊獨立開發(fā)并組合成一個完整SDK,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

本文檔詳細(xì)介紹如何從零開始構(gòu)建一個組件化的Android手游SDK。整個項目采用組件化架構(gòu),將SDK的各個功能模塊拆分獨立開發(fā),最終組合成一個完整的手游SDK。

效果圖

單獨模塊運行

正式包環(huán)境運行

第一章 項目整體架構(gòu)

1.1 架構(gòu)一覽

先來看一下我們項目的整體結(jié)構(gòu):

zujianmodule (根項目)
├── app                      # 游戲主入口模塊
├── app-base                 # SDK核心基礎(chǔ)模塊
├── app-login                # 登錄模塊
├── app-register             # 注冊模塊  
├── app-center               # 個人中心模塊
├── app-changepassword       # 修改密碼模塊
├── app-update               # 強(qiáng)制更新模塊
├── lib-util                 # 工具類庫
├── lib-data                 # 數(shù)據(jù)層庫
├── lib-logging              # 日志庫
├── lib-permissions          # 權(quán)限庫
└── lib-imgloader            # 圖片加載庫

模塊分類:

  • app模塊:業(yè)務(wù)功能模塊(登錄、注冊、個人中心等)
  • lib模塊:公共基礎(chǔ)庫(供所有模塊復(fù)用)

1.2 模塊依賴關(guān)系

app (主模塊)
└── 依賴所有 app-* 模塊
?
app-base (核心基礎(chǔ))
├── 依賴 lib-util
└── 提供:SdkCore、SdkCoreImpl、ModuleMediator、BaseActivity、回調(diào)接口
?
app-login (登錄)
├── 依賴 app-base
└── 提供:LoginActivity
?
app-register (注冊)
├── 依賴 app-base
└── 提供:RegisterActivity
?
app-center (個人中心)
├── 依賴 app-base
└── 提供:CenterActivity
?
app-changepassword (修改密碼)
├── 依賴 app-base
└── 提供:ChangePasswordActivity
?
app-update (強(qiáng)制更新)
├── 依賴 app-base
└── 提供:UpdateActivity

第二章 核心技術(shù)點詳解

2.1 為什么要組件化?

傳統(tǒng)SDK開發(fā)方式:

  • 所有代碼寫在一個模塊里
  • 代碼耦合嚴(yán)重,難以維護(hù)
  • 功能擴(kuò)展困難
  • 多人協(xié)作困難

組件化優(yōu)勢:

  • 模塊解耦:每個功能獨立模塊,職責(zé)單一
  • 獨立運行:開發(fā)階段每個模塊可獨立運行測試
  • 按需加載:發(fā)布時可按需求組合
  • 團(tuán)隊協(xié)作:不同模塊可分配給不同人開發(fā)

2.2 反射式資源加載(核心黑科技)

這是本項目的核心創(chuàng)新點!傳統(tǒng)方式下,每個模塊的Activity都需要在主項目的AndroidManifest中注冊,否則找不到。但我們使用反射技術(shù)實現(xiàn)了自動發(fā)現(xiàn)

TestResourceUtil 工具類

// 反射獲取布局資源
public static int getLayoutId(Context context, String resName) {
    return context.getResources().getIdentifier(resName, "layout", context.getPackageName());
}
?
// 反射獲取字符串資源
public static int getStringId(Context context, String resName) {
    return context.getResources().getIdentifier(resName, "string", context.getPackageName());
}
?
// 反射獲取Drawable資源
public static int getDrawableId(Context context, String resName) {
    return context.getResources().getIdentifier(resName, "drawable", context.getPackageName());
}
?
// 反射獲取ID
public static int getId(Context context, String resName) {
    return context.getResources().getIdentifier(resName, "id", context.getPackageName());
}

在BaseActivity中使用

public abstract class BaseActivity extends Activity {
    
    // 通過布局名稱動態(tài)加載布局
    public void setContentView(String layoutId) {
        // 傳入 "activity_login" 而不是 R.layout.activity_login
        super.setContentView(TestResourceUtil.getLayoutId(mContext, layoutId));
    }
    
    // 通過控件ID名稱查找控件
    public View findViewById(String viewId) {
        // 傳入 "btn_login" 而不是 R.id.btn_login
        return super.findViewById(TestResourceUtil.getId(mContext, viewId));
    }
}

Activity中使用

public class LoginActivity extends BaseActivity {
    @Override
    protected void loadViewLayout() {
        // 直接寫字符串,框架自動找資源!
        setContentView("activity_login");
    }
    
    @Override
    protected void findViewById() {
        // 控件也是字符串形式
        Button btnLogin = findViewById("btn_login");
    }
}

?? 好處:再也不用擔(dān)心模塊間資源ID沖突問題了!每個模塊可以有自己的activity_login.xml!

2.3 模塊初始化機(jī)制

每個功能模塊都需要一個App類實現(xiàn)AppInitial接口,這樣主項目就能在運行時自動初始化所有模塊:

AppInitial接口

public interface AppInitial {
    void init(Application app);
}

登錄模塊的App類

public class App implements ModuleMediator.AppInitial {
    @Override
    public void init(Application app) {
        // 這里可以初始化登錄模塊特有的東西
        // 比如配置第三方登錄SDK
    }
}

ModuleMediator統(tǒng)一初始化

public class ModuleMediator {
    // 每個模塊的App類全限定名
    private static final String APP_LOGIN_CLASS = "com.github.jeffery.login.App";
    private static final String APP_CENTER_CLASS = "com.github.jeffery.center.App";
    private static final String APP_REGISTER_CLASS = "com.github.jeffery.register.App";
    private static final String APP_CHANGEPASSWORD_CLASS = "com.github.jeffery.changepassword.App";
    private static final String APP_UPDATE_CLASS = "com.github.jeffery.update.App";
    
    // 一次性初始化所有模塊
    public static void init(Application app) {
        String[] appClasses = {
            APP_LOGIN_CLASS, 
            APP_CENTER_CLASS,
            APP_REGISTER_CLASS, 
            APP_CHANGEPASSWORD_CLASS, 
            APP_UPDATE_CLASS
        };
        
        for (String claName : appClasses) {
            try {
                Class<?> clz = Class.forName(claName);
                AppInitial obj = (AppInitial) clz.newInstance();
                obj.init(app);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

2.4 路由跳轉(zhuǎn)機(jī)制

類似于ARouter,但更輕量級!使用字符串常量來標(biāo)識目標(biāo)頁面:

public class ModuleMediator {
    // 頁面路由常量
    public static final String ACTIVITY_LOGIN_CLASS = "com.github.jeffery.login.LoginActivity";
    public static final String ACTIVITY_CENTER_CLASS = "com.github.jeffery.center.CenterActivity";
    public static final String ACTIVITY_REGISTER_CLASS = "com.github.jeffery.register.RegisterActivity";
    public static final String ACTIVITY_CHANGEPASSWORD_CLASS = "com.github.jeffery.changepassword.ChangePasswordActivity";
    public static final String ACTIVITY_UPDATE_CLASS = "com.github.jeffery.update.UpdateActivity";
    
    // 單例模式
    private static volatile ModuleMediator instance;
    
    public static ModuleMediator getInstance() {
        if (instance == null) {
            synchronized (ModuleMediator.class) {
                if (instance == null) {
                    instance = new ModuleMediator();
                }
            }
        }
        return instance;
    }
    
    // 跳轉(zhuǎn)Activity
    public void startActivity(Activity activity, String className) {
        startActivity(activity, className, null);
    }
    
    public void startActivity(Activity activity, String className, Bundle bundle) {
        try {
            Class<?> clazz = Class.forName(className);
            Intent intent = new Intent(activity, clazz);
            if (bundle != null) {
                intent.putExtras(bundle);
            }
            activity.startActivity(intent);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            Toast.makeText(activity, "找不到" + e.getMessage(), Toast.LENGTH_SHORT).show();
        }
    }
}

使用示例

// 跳轉(zhuǎn)到登錄頁
ModuleMediator.getInstance().startActivity(this, 
    ModuleMediator.ACTIVITY_LOGIN_CLASS);
?
// 帶參數(shù)跳轉(zhuǎn)到注冊頁
Bundle params = new Bundle();
params.putString("from", "login");
ModuleMediator.getInstance().startActivity(this, 
    ModuleMediator.ACTIVITY_REGISTER_CLASS, params);

第三章 核心功能實現(xiàn)

3.1 SDK核心類設(shè)計

SdkCore抽象類(定義規(guī)范):

public abstract class SdkCore {
    // 初始化
    public abstract void init(Context context);
    
    // 登錄
    public abstract void login(LoginCallback callback);
    
    // 支付
    public abstract void pay(PayParams params, PayCallback callback);
    
    // 登出
    public abstract void logout(LogoutCallback callback);
    
    // 退出游戲
    public abstract void exitGame(ExitCallback callback);
    
    // 數(shù)據(jù)上報
    public abstract void reportData(String eventId, Object params);
    
    // 生命周期
    public abstract void onCreate();
    public abstract void onStart();
    public abstract void onResume();
    public abstract void onPause();
    public abstract void onStop();
    public abstract void onDestroy();
}

SdkCoreImpl實現(xiàn)類(單例模式):

public class SdkCoreImpl extends SdkCore {
    
    private static volatile SdkCoreImpl instance;
    private Context mContext;
    private boolean isInitialized = false;
    private String currentUserId;
    private String currentUserName;
    private String currentToken;
    
    private SdkCoreImpl() {
        // 私有構(gòu)造函數(shù)
    }
    
    public static SdkCoreImpl getInstance() {
        if (instance == null) {
            synchronized (SdkCoreImpl.class) {
                if (instance == null) {
                    instance = new SdkCoreImpl();
                }
            }
        }
        return instance;
    }
    
    @Override
    public void init(Context context) {
        this.mContext = context.getApplicationContext();
        this.isInitialized = true;
    }
    
    // ... 其他方法實現(xiàn)
}

3.2 回調(diào)接口設(shè)計

所有回調(diào)繼承自基礎(chǔ)接口:

// 基礎(chǔ)回調(diào)
public interface SdkCallback {
    void onSuccess(Object data);
    void onFailure(int code, String msg);
}
?
// 登錄回調(diào)
public interface LoginCallback extends SdkCallback {
    void onLoginSuccess(String userId, String userName, String token);
    void onLoginCancel();
}
?
// 支付回調(diào)
public interface PayCallback extends SdkCallback {
    void onPaySuccess(String orderId, String productId);
    void onPayCancel();
    void onPayPending(String msg);
}
?
// 登出回調(diào)
public interface LogoutCallback extends SdkCallback {
    void onLogoutSuccess();
}
?
// 退出游戲回調(diào)
public interface ExitCallback extends SdkCallback {
    void onConfirmExit();
    void onCancelExit();
}

3.3 支付參數(shù)類

public class PayParams {
    private String productId;      // 商品ID
    private String productName;    // 商品名稱
    private int price;            // 價格(分)
    private String currency;       // 貨幣類型
    private String orderId;        // 訂單號
    private String roleId;         // 角色I(xiàn)D
    private String roleName;       // 角色名稱
    private String serverId;        // 服務(wù)器ID
    private String serverName;      // 服務(wù)器名稱
    private String extData;        // 擴(kuò)展數(shù)據(jù)
    
    // Getter and Setter...
}

第四章 模塊創(chuàng)建步驟

4.1 創(chuàng)建新模塊

假設(shè)我們要創(chuàng)建一個"禮包"模塊 app-gift

1. 在settings.gradle中添加

include ':app-gift'

2. 創(chuàng)建build.gradle

plugins {
    id 'com.android.library'
}
?
android {
    compileSdk buildVersion.compileSdk
    
    defaultConfig {
        minSdk buildVersion.minSdk
        targetSdk buildVersion.targetSdk
        
        // 開發(fā)階段可以獨立運行
        if (!isRelease) {
            applicationId 'com.github.jeffery.gift'
            versionCode 1
            versionName '1.0'
        }
    }
}
?
// 資源前綴,避免資源名沖突
android.resourcePrefix 'gift_'
?
dependencies {
    // 依賴基礎(chǔ)模塊
    api project(':app-base')
}

3. 創(chuàng)建包結(jié)構(gòu)和類

app-gift/src/main/java/com/github/jeffery/gift/
├── App.java              # 模塊初始化類
├── GiftActivity.java     # 禮包Activity
└── ...

4. 創(chuàng)建App類

package com.github.jeffery.gift;
?
import android.app.Application;
import com.github.jeffery.utils.ModuleMediator;
?
public class App implements ModuleMediator.AppInitial {
    @Override
    public void init(Application app) {
        // 初始化禮包模塊
    }
}

5. 在ModuleMediator中添加路由

public static final String ACTIVITY_GIFT_CLASS = "com.github.jeffery.gift.GiftActivity";

4.2 資源文件規(guī)范

為避免資源沖突,每個模塊的資源都要有模塊前綴

模塊布局前綴字符串前綴顏色前綴尺寸前綴
app-loginlogin_login_login_login_
app-registerregister_register_register_register_
app-centercenter_center_center_center_
app-giftgift_gift_gift_gift_

示例

  • activity_login.xmllogin_activity.xml
  • btn_loginlogin_btn_submit
  • @string/login_hint@string/login_hint

第五章 集成到游戲項目

5.1 主項目build.gradle配置

dependencies {
    implementation project(':app-base')
    implementation project(':app-login')
    implementation project(':app-register')
    implementation project(':app-center')
    implementation project(':app-changepassword')
    implementation project(':app-update')
}

5.2 Application初始化

public class GameApplication extends Application {
?
    @Override
    public void onCreate() {
        super.onCreate();
        
        // 1. 初始化所有SDK模塊
        ModuleMediator.init(this);
        
        // 2. 初始化SDK核心
        SdkCoreImpl.getInstance().init(this);
    }
}

5.3 生命周期集成

public class MainActivity extends AppCompatActivity {
?
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SdkCoreImpl.getInstance().onCreate();
    }
?
    @Override
    protected void onStart() {
        super.onStart();
        SdkCoreImpl.getInstance().onStart();
    }
?
    @Override
    protected void onResume() {
        super.onResume();
        SdkCoreImpl.getInstance().onResume();
    }
?
    @Override
    protected void onPause() {
        super.onPause();
        SdkCoreImpl.getInstance().onPause();
    }
?
    @Override
    protected void onStop() {
        super.onStop();
        SdkCoreImpl.getInstance().onStop();
    }
?
    @Override
    protected void onDestroy() {
        super.onDestroy();
        SdkCoreImpl.getInstance().onDestroy();
    }
}

5.4 常用API調(diào)用

登錄

SdkCoreImpl.getInstance().login(new LoginCallback() {
    @Override
    public void onLoginSuccess(String userId, String userName, String token) {
        Log.d("Login", "登錄成功!userId=" + userId);
    }
    
    @Override
    public void onLoginCancel() {
        Log.d("Login", "用戶取消登錄");
    }
    
    @Override
    public void onSuccess(Object data) {}
    
    @Override
    public void onFailure(int code, String msg) {
        Log.e("Login", "登錄失?。? + msg);
    }
});

支付

PayParams params = new PayParams();
params.setProductId("com.game.gems_100");
params.setProductName("100鉆石");
params.setPrice(100);
?
SdkCoreImpl.getInstance().pay(params, new PayCallback() {
    @Override
    public void onPaySuccess(String orderId, String productId) {
        Log.d("Pay", "支付成功!");
    }
    // ...
});

數(shù)據(jù)上報

// 簡單事件
SdkCoreImpl.getInstance().reportData("level_start", null);
?
// 帶參數(shù)事件
Map<String, Object> params = new HashMap<>();
params.put("level_id", 1);
SdkCoreImpl.getInstance().reportData("level_complete", params);

第六章 開發(fā)與發(fā)布模式

6.1 開發(fā)模式(isRelease = false)

// env.gradle
isRelease = false

特點:

  • 每個模塊都有獨立的applicationId
  • 可以獨立安裝運行調(diào)試
  • 便于團(tuán)隊成員獨立開發(fā)

6.2 發(fā)布模式(isRelease = true)

// env.gradle
isRelease = true

特點:

  • 所有模塊合并為一個SDK
  • 只生成一個applicationId
  • 減少包體積

第七章 常見問題解答

Q1: 如何添加新功能模塊?

  1. 創(chuàng)建新模塊(參考第四章)
  2. 在ModuleMediator中添加路由常量
  3. 在settings.gradle中include
  4. 在主模塊build.gradle中添加依賴

Q2: 模塊間如何通信?

通過ModuleMediator單例進(jìn)行通信,也可以直接使用SdkCoreImpl的實例方法。

Q3: 資源沖突怎么辦?

每個模塊使用獨立的資源前綴(通過android.resourcePrefix配置),加上反射式加載,不會有ID沖突。

Q4: 如何調(diào)試單個模塊?

在env.gradle中設(shè)置isRelease = false,該模塊就可以獨立安裝運行。

附錄:目錄結(jié)構(gòu)參考

項目根目錄/
├── app.gradle              # app模塊配置
├── build.gradle            # 根項目配置
├── env.gradle              # 環(huán)境變量配置
├── settings.gradle         # 模塊列表
├── app/                    # 游戲主模塊
├── app-base/               # SDK基礎(chǔ)模塊
│   └── src/main/java/com/github/jeffery/utils/
│       ├── SdkCore.java
│       ├── SdkCoreImpl.java
│       ├── ModuleMediator.java
│       ├── BaseActivity.java
│       ├── LoginCallback.java
│       ├── PayCallback.java
│       └── ...
├── app-login/              # 登錄模塊
├── app-register/           # 注冊模塊
├── app-center/             # 個人中心模塊
├── app-changepassword/     # 修改密碼模塊
├── app-update/             # 強(qiáng)制更新模塊
├── lib-util/               # 工具庫
├── lib-data/               # 數(shù)據(jù)庫
├── lib-logging/            # 日志庫
├── lib-permissions/        # 權(quán)限庫
└── lib-imgloader/          # 圖片加載庫

總結(jié)

本項目通過以下技術(shù)實現(xiàn)了一個輕量級的Android手游SDK組件化方案:

  1. 反射式資源加載 - 解決資源ID沖突問題
  2. ModuleMediator - 統(tǒng)一模塊初始化和頁面路由
  3. AppInitial接口 - 模塊熱插拔
  4. 單例模式 - 核心類全局唯一實例
  5. 回調(diào)接口 - 異步通信標(biāo)準(zhǔn)化

整個方案不依賴任何第三方路由框架,代碼量少,易于理解和維護(hù),非常適合中小型手游SDK開發(fā)。

到此這篇關(guān)于Android手游SDK組件化開發(fā)南的文章就介紹到這了,更多相關(guān)Android手游SDK組件化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

中方县| 济源市| 隆化县| 靖边县| 西和县| SHOW| 仁怀市| 虞城县| 吉林市| 郸城县| 卓尼县| 大连市| 侯马市| 涟源市| 师宗县| 昌平区| 苏尼特左旗| 涟源市| 和平县| 吴川市| 龙里县| 鹤庆县| 隆子县| 台湾省| 堆龙德庆县| 和田县| 勐海县| 禹城市| 临湘市| 莱西市| 稷山县| 白水县| 万全县| 渑池县| 耿马| 陇川县| 吴江市| 定日县| 高碑店市| 吉木萨尔县| 武功县|