开始做一个安卓小游戏,没有想到要去热更新它,结果做完才想到,有bug怎么办…
于是就有了下面的踩坑之旅。
新建一个Empty Activity项目
点击完成后,删除红框内容无用内容
变更后的AndroidManifest.xml文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cn.linyisonger.callme">
<application >
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
intent-filter>
activity>
application>
manifest>
添加一个测试的静态方法
修改继承自Activity
修改构建文件
构建arr包
新建一个Unity工程
Build Settings… Ctrl+Shift+B
切换至Android平台
将生成好的arr包放入Plugins\Android
目录下
新建脚本调用它
新建Test脚本文件
using UnityEngine;
using UnityEngine.UI;
public class Test : MonoBehaviour
{
public Text showResult;
private void Start()
{
var jo = new AndroidJavaObject("cn.linyisonger.android.MainActivity");
int sum = jo.CallStatic<int>("add", 1, 3);
showResult.text = sum.ToString();
}
}
新建一个Text随便改改样式、将脚本挂在Canvas上(当然挂在那里都是可以的,我就随便挂一下)、将Text组件拖至脚本的showResult字段上。
打包测试
添加场景、选择运行设备、构建并运行
效果
示意图 有点糙
将classes.jar
包引入项目中来D:\Unity\2020.3.20f1c1\Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes
右键添加类库
将classes.jar设置为仅编译时构建,打包时不包含此文件(Unity打包会带上)
implementation files('libs\\classes.jar') // 当前
compileOnly fileTree(dir: "libs",includes: ["*.jar"]) // 修改
添加安装方法
MainActivity.java
package cn.linyisonger.callme;
import androidx.core.content.FileProvider;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import com.unity3d.player.UnityPlayer;
import java.io.File;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public static int add(int a, int b) {
return a + b;
}
public static void install(String apkFullPath){
Intent intent = new Intent(Intent.ACTION_VIEW);
File file = new File(apkFullPath);
if (Build.VERSION.SDK_INT >= 24) {
Uri apkUri = FileProvider.getUriForFile(UnityPlayer.currentActivity.getApplicationContext(), UnityPlayer.currentActivity.getPackageName() +".fileprovider", file);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
} else {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
}
UnityPlayer.currentActivity.startActivity(intent);
}
}
构建arr包放置在Unity工程中
设置包名
添加filepaths.xml文件,放在Android/res/xml下
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="download" path="Android/data/cn.LinYisonger.CallAndroid/files/"/>
paths>
添加AndroidManifest.xml文件,放在Android下
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET">uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<application>
<provider android:name="androidx.core.content.FileProvider" android:authorities="cn.LinYisonger.CallAndroid.fileprovider" android:grantUriPermissions="true" android:exported="false" android:usesCleartextTraffic="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" />
provider>
<activity android:name="com.unity3d.player.UnityPlayerActivity" android:theme="@style/UnityThemeSelector">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
activity>
application>
manifest>
添加更新脚本
using System;
using System.Collections;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class Test1 : MonoBehaviour
{
///
/// 版本模型
///
public class VersionModel
{
///
/// Id
///
public long id;
///
/// 程序Key值
///
public string key;
///
/// 编号
///
public string no;
///
/// 描述
///
public string desc;
///
/// 安卓包路径
///
public string apkUrl;
}
public delegate void LoadingAction(float progress);
public delegate void VersionAction(VersionModel version);
private VersionModel CurrentVersion;
private string path => Application.persistentDataPath + "/update.apk";
public Text UpdateText;
private void Start()
{
StartCoroutine(GetCurrentVersion((v) =>
{
if (v.no != Application.version)
{
StartCoroutine(Download((p) =>
{
// 下载进度
UpdateText.text = (p * 100).ToString("0.00");
},
() =>
{
// 下载完成
UpdateText.text = "下载完成";
// 安装
Install();
}));
}
}));
}
public IEnumerator GetCurrentVersion(VersionAction action)
{
UnityWebRequest webRequest = UnityWebRequest.Get("http://y.linyisonger.cn/api/version/GetTheLatestVersion?key=cn.LinYisonger.CallAndroid");
yield return webRequest.SendWebRequest();
CurrentVersion = JsonUtility.FromJson<VersionModel>(webRequest.downloadHandler.text);
action.Invoke(CurrentVersion);
}
public IEnumerator Download(LoadingAction loading, Action done)
{
UnityWebRequest webRequest = UnityWebRequest.Get(CurrentVersion.apkUrl);
webRequest.SendWebRequest();
while (!webRequest.isDone)
{
loading(webRequest.downloadProgress);
yield return 0;
}
File.WriteAllBytes(path, webRequest.downloadHandler.data);
done();
yield return null;
}
public void Install()
{
var jo = new AndroidJavaObject("cn.linyisonger.callme.MainActivity");
jo.CallStatic("install", path);
}
}
构建调试然后就会报错
WARNING: The option setting 'android.enableR8=false' is deprecated.
It will be removed in version 5.0 of the Android Gradle plugin.
You will no longer be able to disable R8
将构建的版本调整为3.4.0
构建调试打开应用闪退啦!
找了很久原来是少引用了依赖库
# 添加依赖支持
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
构建调试