找回密码
 立即注册
查看: 473|回复: 2

unity5.0 打包出来的apk 为什么闪退?

[复制链接]
发表于 2021-12-24 17:14 | 显示全部楼层 |阅读模式
开篇之前,请先阅读雨松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 + ".R$" + the_class);
                    
        id = the_r_class.getField(the_name).getInt(the_r_class);
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
   
    return id;
}调用的话是这样:
builder.setIcon(GetIdFromR(this, "drawable", "app_icon"));
于是,我们见到了久违的弹出框:


最后的最后,我讨厌雨松MOMO叼着奶嘴的头像。
2016.3.17:修改初版完成。
2016.3.18:错别字修改,吐槽添加完毕。
=================== 以下是原答案 ===================
Unity接入Android sdk有两种方式:一是Android插件的形式导入unity(unity5注意package的问题hack即可,具体优雅解决还待细查)。二是unity导出Android工程来做。两种方法都应该是可行的,具体闪退原因看Logcat应该能找出原因,猜测是主启动活动没写全路径。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2021-12-24 17:17 | 显示全部楼层
开篇之前,请先阅读雨松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 + ".R$" + the_class);
                    
        id = the_r_class.getField(the_name).getInt(the_r_class);
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
   
    return id;
}调用的话是这样:
builder.setIcon(GetIdFromR(this, "drawable", "app_icon"));
于是,我们见到了久违的弹出框:


最后的最后,我讨厌雨松MOMO叼着奶嘴的头像。
2016.3.17:修改初版完成。
2016.3.18:错别字修改,吐槽添加完毕。
=================== 以下是原答案 ===================
Unity接入Android sdk有两种方式:一是Android插件的形式导入unity(unity5注意package的问题hack即可,具体优雅解决还待细查)。二是unity导出Android工程来做。两种方法都应该是可行的,具体闪退原因看Logcat应该能找出原因,猜测是主启动活动没写全路径。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2021-12-24 17:26 | 显示全部楼层
官方说法是 5.0的打包确实存在Bug,在我回答你的时候也就是5.3的时候版本已经稳定了。
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-16 08:48 , Processed in 0.093692 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表