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

猜你喜欢

转载自blog.csdn.net/cgExplorer/article/details/105371623