unity在android平台发布apk,应用启动黑屏时间过长的问题解决

如果将unity发布的apk工程放到低配置的android平台上启动着实太慢了,因为unity从启动开始到看见场景界面需要经过,unity刚启动的黑屏、Splash显示、然后游戏场景加载出来这个过程有的时候能达到十秒,但是这几个过程在unityAPK启动过程中,无法避免,所有在这个就是让用户在这个过程中看见一个动画层,利用这个动画层覆盖unity显示的黑屏和splash图标。大概思路如下:

1、Unity生成的Android应用必然要从这个UnityPlayerActivity启动,那么他的启动Splash view必然显示在这个activity里面;

2、因为每次启动apk都会先执行OnCreate方法,所有在onCreate方法里面在创建一个view来覆盖Splash。

3、在这个启动页面中我们也可以添加动画和各种像填入显示的效果和声音。

4、最后我们在unity场景初始化完成后我们在unity里面将新创建的View隐藏并销毁上面的动画和声音即可。

一、android studio3.5.3工程准备。

1、创建activity工程

2、将unity版本对应的classes.jar导入android工程

3、修改MainActivity类继承UnityPlayerActivity

4、修改AndroidManifest.xml

修改android:theme的值为android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"

添加<meta-data android:name="unityplayer.UnityActivity" android:value="true" />

5、修改build.gradle

修改apply plugin的值为apply plugin: 'com.android.library'

去掉applicationId "com.MMPark.splash"//com.MMPark.splash为你的项目包名

6、如果想将项目打包jar给unity使用可以在build.gradle添加如下代码。(如果你想直接使用aar包可以不添加如下代码)

def UNITY_BASENAME = "unity";
def SDK_VERSION = "${android.defaultConfig.versionName}";
def sdkDestinationPath = "build/jar/";
def zipFile = file('build/intermediates/packaged-classes/debug/classes.jar'); // 待打包文件位置
task deleteBuild(type: Delete) {
    delete sdkDestinationPath + UNITY_BASENAME + SDK_VERSION + ".jar"
}
task makeJar(type: Jar) {
    exclude('com/jason/test/')
    from zipTree(zipFile)
    baseName = UNITY_BASENAME + SDK_VERSION
    destinationDir = file(sdkDestinationPath)

}
makeJar.dependsOn(deleteBuild, build)

7、修改MainActivity类,我们将android的主要启动界面流程和关闭都写在这里。

package com.MMPark.splash;

import java.util.Locale;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.media.AudioManager;
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;

import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;

public class MainActivity extends UnityPlayerActivity
{
    static final String TAG = "MainActivity测试";
    private ImageView bgView = null;
    private View view = null;
    AnimationDrawable animationDrawable = null;

    @SuppressLint("NewApi") @Override
    protected void onCreate(Bundle arg0)
    {
        super.onCreate(arg0);

        //先为画布添加一层背景
        bgView=new ImageView(this);
        String lanStr=Locale.getDefault().getLanguage();
        String bgName="splash_bg_en";
        if(lanStr.equals("zh"))
        {
            bgName="splash_bg_zh";
        }
        Log.d(TAG, "System Lan:"+bgName);
        int splash_bg=getResources().getIdentifier(bgName, "drawable", getPackageName());
        bgView.setBackgroundResource(splash_bg);
        mUnityPlayer.addView(bgView);

        //获取屏幕尺寸等相关信息
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        float scaleX=dm.widthPixels/1024f;
        float scaleY=dm.heightPixels/600f;
        Log.d(TAG, "Screen Width:"+dm.widthPixels+";Screen Height:"+dm.heightPixels);
        //将我们创建的活动页添加到应用画布上
        LayoutInflater flater = LayoutInflater.from(this);
        int layoutID=getResources().getIdentifier("activity_main", "layout", getPackageName());
        view = flater.inflate(layoutID, null);

        int frame_id=view.getResources().getIdentifier("splash_frame", "id", getPackageName());
        ImageView frameView=(ImageView)view.findViewById(frame_id);//new ImageView(this);
        frameView.setBackgroundResource(R.drawable.sequence);
        mUnityPlayer.addView(view);

        //根据屏幕调节图像比例
        frameView.setScaleX(scaleX);
        frameView.setScaleY(scaleY);

        //启用动画,此处利用程序动态控制方便后面关闭
        animationDrawable = (AnimationDrawable) frameView.getBackground();
        animationDrawable.start();
    }
    public void HideSplash()
    {
        Log.d(TAG, "HideSplash");
        new Handler(Looper.getMainLooper()).post(new Runnable()
        {
            @Override
            public void run()
            {
                Log.d(TAG, "HideSplash run");
                animationDrawable.stop();
                mUnityPlayer.removeView(bgView);
                mUnityPlayer.removeView(view);
//				((ViewGroup)bgView.getParent()).removeView(bgView);
//				((ViewGroup)view.getParent()).removeView(view);
                bgView=null;
                view=null;
                animationDrawable=null;
            }
        });
    }
}

8、然后我们在xml中构建自己喜欢的动画和启动界面样式即可(下面是我个人的布局文件和动画文件)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/splash_bg"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="2.14"
            android:orientation="horizontal" >
            <ImageView
                android:id="@+id/splash_frame"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
        </LinearLayout>

</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:duration="300" android:drawable="@drawable/loading_1" />
    <item android:duration="300" android:drawable="@drawable/loading_2" />
    <item android:duration="300" android:drawable="@drawable/loading_3" />
    <item android:duration="300" android:drawable="@drawable/loading_4" />
</animation-list>

9、以上完成android工程,打包发布给unity使用即可,以下是我的android工程目录:

二、unity工程

1、unity工程很简单了,只需要调用即可,以下是调用类:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/****************************************************
	作者:cg
	功能:
*****************************************************/
public class SplashCtrl : MonoBehaviour
{
    private void Start()
    {
        Debug.Log("开始界面");
    }
    private void Update()
    {
        if(Input.GetKeyDown(KeyCode.Escape))
        {
            Application.Quit();
        }
        if(Input.GetKeyDown(KeyCode.DownArrow))
        {
            SplashClose();
        }
    }

    private void SplashClose()
    {
        Debug.Log("关闭页面");
        //能访问到,但是在munityplayer报错
        //AndroidJavaObject jo = new AndroidJavaObject("com.MMPark.splash.MainActivity");
        //jo.Call("HideSplash");
        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
        jo.Call("HideSplash");
    }
}

2、工程目录结构如下:(这里没有利用aar包,因为总是提示内部文件有重复,如果大家找到好的利用aar包的文章或资源希望可以留言讨论O(∩_∩)O)

3、最后打包发布apk完成,这里给大家分享一份完整工程,希望对大家有帮助https://download.csdn.net/download/cgExplorer/12311842

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity开发的Android应用程序进入时间可能有多个原因。 1.资源加载时间Unity应用程序启动时,需要加载各种资源,例如游戏场景、纹理、音频、脚本等。如果资源较多或者资源文件较大,加载时间就会变,导致进入时间。 2.编译和打包时间:在Unity中,将应用程序编译和打包成Android应用需要一定时间。如果项目代码较多或者有复杂的逻辑,编译和打包的时间就会增加,从而导致时间。 3.设备性能不足:如果用户的Android设备性能较低,如处理器速度慢、内存较小,那么启动Unity应用程序的时间可能会比较。这是因为设备性能不足导致Unity引擎初始化和资源加载速度变慢。 4.其他耗时操作:除了资源加载和编译打包,还可能有其他耗时操作导致进入时间,例如初始化插件、网络请求、加载广告等。这些操作都可能会增加进入时间解决这个问题可以从以下几个方面入手: 1.优化资源加载:合理使用资源压缩和分包技术,减小资源文件大小,降低加载时间。另外,可以进行异步加载,避免阻塞主线程。 2.优化代码逻辑:简化代码结构,减少不必要的计算和操作,提高应用程序的启动速度。 3.兼容性测试和优化:针对不同的Android设备进行兼容性测试,发现性能较低的设备并进行相应的优化。 4.使用启动图或进度提示:可以在应用程序启动时显示一张启动图或者添加一个进度提示,从而让用户感知到应用程序正在加载,减少时间的影响。 综上所述,Unity Android应用程序进入时间可能是由于资源加载时间、编译和打包时间、设备性能不足以及其他耗时操作等原因造成的。通过优化资源加载、代码逻辑、兼容性测试和增加启动图或进度提示等方式可以减少时间

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值