|
开篇之前,请先阅读雨松MOMO大神的两篇文章:
- Unity3D研究院之打开Activity与调用JAVA代码传递参数(十八)
- Unity3D研究院之与Android相互传递消息(十九)
到这里如果你用的是Unity 4.x 的话就可以跳过剩下的所有文字了,教程结束,用Unity5的话请继续往下看:
拜读完两篇大作之后你觉得有雨松MOMO大神光环加身,打开Unity5和简陋的Eclipse准备撸代码,直到你遇到了下面的错误:
WTF! 你重新看了一遍教程确认自己按照教程一步步走下来的,甚至直接用大神的工程来编译也是这个错误,去评论区找也是相关的评论而没有解决方案。
WTFx2! 这时候你才确定遇到了某种坑,这种坑需要自己来填。
看错误是在将classes文件转换成dex文件时,下面这这几个class文件已经存在了:
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/my/test/R;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/my/test/R$attr;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/my/test/R$drawable;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/my/test/R$string;
Uncaught translation error: java.lang.IllegalArgumentException: already added: Lcom/my/test/R$style; 我们到Eclipse生成的classes目录(bin\classes)中看一下,发现除了我们自己的 MainActivity 的class,Eclipse还附赠了 BuildConfig和 R 相关的class文件,回忆我们之前是用下面的命令将所有classes打包的,那么错误的原因的很好解释了:Unity打包时会帮我们生成R相关的classes,而这个过程会和Eclipse生成的classes文件相冲突。
“万恶”的打包jar命令: jar -cvf test.jar * 问题到了这里就很好解决了,如果要使用jar命令打包,需要删除 BuildConfig 和 R相关的classes再进行打包。其实通过下面的两种方式可以绕过这个问题:
- 用Eclipse导出jar文件。具体操作是:右键 -> Export -> Java/JAR file -> 勾选src下面的包全部导出jar。这种方法不会导出多余的文件,编译不会就不会报错了,这是推荐方式。
- 在Eclipse里面改包名为不和包名相同的任意值,例如com.never.mind。这种方法的话Eclipse会将多余的文件生成到com/never/mind目录下面,因为不和最终的包名相同,所以用jar命令打包不会导致冲突。
正确导出的应该的是右边的这个jar:
到了这里你以为问题已经解决了,直到你膝盖又中了一箭。
老大:我们需要在游戏的退出框里加个游戏的icon。
你:好,我去网上找一找。
然后你找到了这样的代码:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("退出");
builder.setMessage("是否退出游戏?");
builder.setPositiveButton("確定", new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
finish();
}
});
builder.setNegativeButton("取消", new OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
{
dialog.dismiss();
}
});
builder.setIcon(R.drawable.app_icon); // 很急很关键
AlertDialog dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
dialog.show();运行的结果是这样的:
WTFx3! 这张图你是谁?人与机器之间最基本的信任在哪里?
于是我们尝试反编译APK看问题在哪里,发现是Unity5 在最前面自动给我们加了个app_banner:
到了这里我们只能将所有用到R相关的东西全用反射来拿了,方法大概长成下面这个样子:
public static int GetIdFromR(Context context, String the_class, String the_name)
{
int id = -1;
try
{
String packageName = context.getPackageName();
Class<?> the_r_class = Class.forName(packageName + &#34;.R$&#34; + the_class);
id = the_r_class.getField(the_name).getInt(the_r_class);
}
catch(Exception e)
{
e.printStackTrace();
}
return id;
}调用的话是这样:
builder.setIcon(GetIdFromR(this, &#34;drawable&#34;, &#34;app_icon&#34;)); 于是,我们见到了久违的弹出框:
最后的最后,我讨厌雨松MOMO叼着奶嘴的头像。
2016.3.17:修改初版完成。
2016.3.18:错别字修改,吐槽添加完毕。
=================== 以下是原答案 ===================
Unity接入Android sdk有两种方式:一是Android插件的形式导入unity(unity5注意package的问题hack即可,具体优雅解决还待细查)。二是unity导出Android工程来做。两种方法都应该是可行的,具体闪退原因看Logcat应该能找出原因,猜测是主启动活动没写全路径。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|