前言 :
各位同学的大家好 , 最近在学习鸿蒙开发, 因为我是从事手游SDK 开发的 之前也写过iOS 手游sdk 开发和安卓手游sdk 开发(kotlin 版本)
效果图:
image.png
image.png
设计思路
我们需要封装 init login servicelogin updateuserinfo 等对外接口给到游戏去调用
package com.example.myapplication;
import com.example.myapplication.bean.BackInfo;
import com.example.myapplication.bean.RoleInfo;
import com.example.myapplication.bean.ServiceInfo;
import com.example.myapplication.lisenter.InitListener;
import com.example.myapplication.lisenter.LoginLisenter;
import com.example.myapplication.lisenter.ServiceListener;
import com.example.myapplication.lisenter.UpdateUserListener;
import com.google.gson.Gson;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;
import ohos.app.Context;
import okhttp3.Call;
import java.util.HashMap;
import java.util.Map;
public class NineFunSdk {
private Boolean initFlag=false;
private static NineFunSdk instance;
private NineFunSdk() {
}
public static NineFunSdk getInstance(){
if(instance==null){
synchronized (NineFunSdk.class){
if(instance==null){
instance=new NineFunSdk();
}
}
}
return instance;
}
public void init(InitListener listener){
Map map=new HashMap<>();
map.put("deviceid","2341414");
map.put("system_type","android");
map.put("version","1.1");
map.put("gid","35");
map.put("device","saff");
map.put("device_model","1214141");
map.put("device_model","WEFWF");
map.put("device_model","21E131");
OkHttpUtils.post().url(Config.INIT).params(map)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {
listener.initError();
}
@Override
public void onResponse(String s, int i) {
Gson gson=new Gson();
BackInfo backInfo=gson.fromJson(s,BackInfo.class);
if(backInfo.getCode()==200){
initFlag=true;
listener.initSuccess();
}else{
listener.initError();
}
}
});
}
public void checkLogin(Context context, LoginLisenter lisenter){
if(initFlag){
LoginDialog loginDialog = new LoginDialog(context,lisenter);
loginDialog.show();
}else{
ToastUtils.showInfo(context,"请先调用初始化");
}
}
/**
*
*
* @param serviceInfo
* @param lisenter
*/
public void serviceLogin(ServiceInfo serviceInfo, ServiceListener lisenter){
StringBuilder preSign = new StringBuilder();
preSign.append("sid=").append(serviceInfo.getSid());
preSign.append("&role_id=").append(serviceInfo.getRole_id());
preSign.append("&role_name=").append(serviceInfo.getRole_name());
preSign.append("||").append("0a649d6b-df9f-4583-bf7d-3fae84838519");
Map map=new HashMap<>();
map.put("gid",serviceInfo.getGid());
map.put("sid",serviceInfo.getGid());
map.put("role_name",serviceInfo.getGid());
map.put("role_level",serviceInfo.getGid());
map.put("role_id",serviceInfo.getGid());
map.put("sign",preSign.toString());
OkHttpUtils.post().url(Config.SERVICE_LOGIN).params(map)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {
}
@Override
public void onResponse(String s, int i) {
Gson gson=new Gson();
BackInfo backInfo=gson.fromJson(s,BackInfo.class);
if(backInfo.getCode()==200){
lisenter.serviceLoginSuccess();
}
}
});
}
/**
*
* @param roleInfo
* @param lisenter
*/
public void updateUserInfo(RoleInfo roleInfo, UpdateUserListener lisenter){
StringBuilder preSign = new StringBuilder();
preSign.append("sid=").append(roleInfo.getGid());
preSign.append("&role_id=").append(roleInfo.getRole_id());
preSign.append("&role_name=").append(roleInfo.getRole_name());
preSign.append("||").append("0a649d6b-df9f-4583-bf7d-3fae84838519");
Map map=new HashMap<>();
map.put("gid",roleInfo.getGid());
map.put("sid",roleInfo.getGid());
map.put("role_name",roleInfo.getGid());
map.put("role_level",roleInfo.getGid());
map.put("role_id",roleInfo.getGid());
map.put("sign",preSign.toString());
OkHttpUtils.post().url(Config.UPDATE_USERINFO).params(map)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {
}
@Override
public void onResponse(String s, int i) {
Gson gson=new Gson();
BackInfo backInfo=gson.fromJson(s,BackInfo.class);
if(backInfo.getCode()==200){
lisenter.updateuserSuccess();
}
}
});
}
}
登录框实现:
-
布局
-
布局效果
image.png
具体逻辑
package com.example.myapplication;
import com.example.myapplication.lisenter.LoginLisenter;
import com.google.gson.Gson;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.StringCallback;
import ohos.agp.components.*;
import ohos.agp.utils.LayoutAlignment;
import ohos.agp.utils.TextAlignment;
import ohos.agp.window.dialog.CommonDialog;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import okhttp3.Call;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import static com.example.myapplication.Config.LOGIN_URL;
import static ohos.agp.components.ComponentContainer.LayoutConfig.MATCH_CONTENT;
/**
*
* 创建人:xuqing
* 创建时间:2022年5月12日11:55:53
* 类说明: 登录弹窗
*
*/
public class LoginDialog extends CommonDialog {
static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG");
private Context context;
private Component customComponent;
private TextField account, pswtf;
private String username, password;
private Button loginbtn;
private LoginLisenter lisenter;
public LoginDialog(Context context,LoginLisenter lisenter) {
super(context);
this.context=context;
this.lisenter=lisenter;
setAlignment(TextAlignment.CENTER);
setSize(MATCH_CONTENT, MATCH_CONTENT);
initComponents();
}
private void initComponents() {
customComponent = LayoutScatter.getInstance(context)
.parse(ResourceTable.Layout_dialog_login, null, true);
super.setContentCustomComponent(customComponent);
loginbtn = (Button) customComponent.findComponentById(ResourceTable.Id_logindialogbtn);
account= (TextField) customComponent.findComponentById(ResourceTable.Id_tf_account);
pswtf= (TextField) customComponent.findComponentById(ResourceTable.Id_tf_password);
loginbtn.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
username=account.getText().toString();
password=pswtf.getText().toString();
if(!TextUtils.Isempty(username)&& !TextUtils.Isempty(password)){
Maploginmap=new HashMap<>();
loginmap.put("username",username);
loginmap.put("password",password);
login(loginmap);
}else{
ToastUtils.showInfo(context,"账号密码不能为空");
}
}
});
}
public void login(Map map){
HiLog.warn(LABEL, "Failed to visit %{private}map , ", map.toString());
// ToastUtils.showInfo(context,map.toString());
ToastUtils.showInfo(context,LOGIN_URL);
OkHttpUtils.get().
url(LOGIN_URL)
.params(map)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {
System.out.println("Exception --- > "+e);
}
@Override
public void onResponse(String s, int i) {
System.out.println("okhttpUtilsNet s --- > "+s);
HiLog.warn(LABEL, "Failed to visit %{private}s, ", s);
Gson gson=new Gson();
LofinInfo lofinInfo=gson.fromJson(s,LofinInfo.class);
int code=lofinInfo.getCode();
if(code==200){
ToastUtils.showInfo(context,"登录成功");
lisenter.loginSuccess(s);
LoginDialog.this.destroy();
}
}
});
}
}
-
登录对外接口
public void checkLogin(Context context, LoginLisenter lisenter){
if(initFlag){
LoginDialog loginDialog = new LoginDialog(context,lisenter);
loginDialog.show();
}else{
ToastUtils.showInfo(context,"请先调用初始化");
}
}
-
登录调用
private void login() {
NineFunSdk.getInstance().checkLogin(MainAbility.this, new LoginLisenter() {
@Override
public void loginSuccess(String data) {
System.out.println("data --- > "+data );
}
@Override
public void loginError() {
}
});
}
登录弹窗 里面逻辑也比较简单就是游戏在外部调用SDK 我们在初始化成功以后 我们显示登录弹窗 。然后用户输入账号密码 我们去登录 请求服务器 如果登录成功我们将服务器返回数据结构回调给游戏游戏拿到token和userid 去请求api/token验证接口进行验证登录效果即可
区服上报接口
/**
*
*
* @param serviceInfo
* @param lisenter
*/
public void serviceLogin(ServiceInfo serviceInfo, ServiceListener lisenter){
StringBuilder preSign = new StringBuilder();
preSign.append("sid=").append(serviceInfo.getSid());
preSign.append("&role_id=").append(serviceInfo.getRole_id());
preSign.append("&role_name=").append(serviceInfo.getRole_name());
preSign.append("||").append("0a649d6b-df9f-4583-bf7d-3fae84838519");
Map map=new HashMap<>();
map.put("gid",serviceInfo.getGid());
map.put("sid",serviceInfo.getGid());
map.put("role_name",serviceInfo.getGid());
map.put("role_level",serviceInfo.getGid());
map.put("role_id",serviceInfo.getGid());
map.put("sign",preSign.toString());
OkHttpUtils.post().url(Config.SERVICE_LOGIN).params(map)
.build()
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {
}
@Override
public void onResponse(String s, int i) {
Gson gson=new Gson();
BackInfo backInfo=gson.fromJson(s,BackInfo.class);
if(backInfo.getCode()==200){
lisenter.serviceLoginSuccess();
}
}
});
}
区服登录调用
private void servicelogin() {
ServiceInfo serviceInfo=new ServiceInfo();
serviceInfo.setGid("11");
serviceInfo.setRole_id("11");
serviceInfo.setRole_name("齐天大圣");
serviceInfo.setRole_level("1000");
serviceInfo.setSid("1234");
NineFunSdk.getInstance().serviceLogin(serviceInfo, new ServiceListener() {
@Override
public void serviceLoginSuccess() {
}
@Override
public void serviceLoginError() {
}
});
同理 等级变化更新也是一样的 我就不展开讲了。
-
打包 har
安卓本地库是aar 华为是har 最早以前我用eclipse 开发的时候我是分开打的 jar包和资源 用了android studio 就打包aar了 鸿蒙和安卓差不多的我们需要创建一个library 的本地库
image.png
然后在打包以后在build里面 可以看到我们的har 文件
image.png
最后总结:
鸿蒙的手游sdk 开发 和安卓的手游sdk开发比较类似 不过这里的SDK里面的界面我用的是弹窗 但是在安卓里面我用的是透明的视图activity 安卓里面你也可以用弹窗 这个看具体实现。整个的开发难度不大主要是对外接口的设计 还有就是避免使用三方库 还有就是代码的混淆,对外类和对外接口我们一定不能混淆否则会导致本地库不能正常接入。 最后希望我的文章能帮助到各位解决问题 ,以后我还会贡献更多有用的代码分享给大家。各位同学如果觉得文章还不错 ,麻烦给关注和star,小弟在这里谢过啦!