Unity在Android Activity中加載的時期測試

Unity在Android Activity中加載的時期測試

    之前在研究Unity3D項目接入Android SDK中,發現在Unity項目生命週期與Android並不一樣,無法直接管理Android的生命週期(需要導成Android項目纔可以)。
    而通過Unity版SDK接入Android,發現SDK的生命週期卻沒參與運行。在反編譯後smali文件中加入SDK的生命週期後發現,Unity項目中的生命週期加載要在Android Activity onResume()之後。

Unity生命週期

這裏寫圖片描述

Android Activity生命週期

這裏寫圖片描述

對比

兩者顯然無法對比。
爲確定Unity的生命加載週期在Android中的時期,爲此我們準備一個測試Demo。

UnityDemo

1.新建一個Unity項目

點擊Main Camara–>Add Component–>New Script–>UnityAndroidDemo.cs
在生命週期內添加打印信息,cs內容如下:

using UnityEngine;
using System.Collections;

public class UnityAndroidDemo : MonoBehaviour {

    void Awake()
    {
        print("UnityAndroidDemo Unity is on Awake()");
    }

    // Use this for initialization
    void Start () {
        print("UnityAndroidDemo Unity is on Start()");
    }

    // Update is called once per frame
    void Update () {

    }
}
2.導出成Android項目

File–>BuildSettings–>設置包名–>Platform–>Android–>Google Android Project–>Export

3.用Eclipse打開導出的Android項目,打印生命週期信息

編輯後的UnityPlayerActivity的代碼如下:

package com.yuchenfw.unityandroiddemo;

import com.unity3d.player.*;
import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;

public class UnityPlayerActivity extends Activity
{
    protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code

    // Setup activity layout
    @Override protected void onCreate (Bundle savedInstanceState)
    {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        Log.e("UnityAndroidDemo","UnityAndroidDemo Android is onCreate()");
        getWindow().setFormat(PixelFormat.RGBX_8888); // <--- This makes xperia play happy

        mUnityPlayer = new UnityPlayer(this);
        setContentView(mUnityPlayer);
        mUnityPlayer.requestFocus();
    }

    // Quit Unity
    @Override protected void onDestroy ()
    {
        mUnityPlayer.quit();
        super.onDestroy();
        Log.e("UnityAndroidDemo","UnityAndroidDemo Android is onDestroy()");
    }

    // Pause Unity
    @Override protected void onPause()
    {
        super.onPause();
        mUnityPlayer.pause();
        Log.e("UnityAndroidDemo","UnityAndroidDemo Android is onPause()");
    }

    // Resume Unity
    @Override protected void onResume()
    {
        super.onResume();
        mUnityPlayer.resume();
        Log.e("UnityAndroidDemo","UnityAndroidDemo Android is onResume()");
    }

    @Override protected void onStart()
    {
        super.onResume();
        mUnityPlayer.resume();
        Log.e("UnityAndroidDemo","UnityAndroidDemo Android is onStart()");
    }


    // This ensures the layout will be correct.
    @Override public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        mUnityPlayer.configurationChanged(newConfig);
    }

    // Notify Unity of the focus change.
    @Override public void onWindowFocusChanged(boolean hasFocus)
    {
        super.onWindowFocusChanged(hasFocus);
        mUnityPlayer.windowFocusChanged(hasFocus);
    }

    // For some reason the multiple keyevent type is not supported by the ndk.
    // Force event injection by overriding dispatchKeyEvent().
    @Override public boolean dispatchKeyEvent(KeyEvent event)
    {
        if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
            return mUnityPlayer.injectEvent(event);
        return super.dispatchKeyEvent(event);
    }

    // Pass any events not handled by (unfocused) views straight to UnityPlayer
    @Override public boolean onKeyUp(int keyCode, KeyEvent event)     { return mUnityPlayer.injectEvent(event); }
    @Override public boolean onKeyDown(int keyCode, KeyEvent event)   { return mUnityPlayer.injectEvent(event); }
    @Override public boolean onTouchEvent(MotionEvent event)          { return mUnityPlayer.injectEvent(event); }
    /*API12*/ public boolean onGenericMotionEvent(MotionEvent event)  { return mUnityPlayer.injectEvent(event); }
}

4.運行

run as –>Android Application
日誌如下:
這裏寫圖片描述
紅色是Android Activity的加載,綠色是Unity生命週期加載

5.結論

從日誌可以看出,Unity的加載是在Android的onResume()之後進行的,因此在Unity中接入Android 的SDK時,涉及到的生命週期問題一定要在導成Android項目中進行,否則因SDK加載的過晚可能會導致功能的異常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章