动态

详情 返回 返回

Launcher 桌面源碼筆記二 - 动态 详情

車模桌面加載成功後,需要各種交互

切換桌面處理

先補充如何切換桌面,初始化需要指定一個默認桌面,初始化其實兩個桌面都會一起加載,假設默認是車模桌面,地圖將不會初始化操作,但是地圖桌面會內嵌到Launcher中

兩個桌面是互斥的,基於這種模式下,就需要隱藏另一個桌面,因為切換動效的緣故,這裏直接使用setTranslationX移出屏幕外處理

為了讓兩個桌面互斥,需要通過 mActivityManager.moveTaskToFront(getTaskId(), 0) 方法讓兩個taskview內嵌的activity只能一個處於前台,另一個pause

public void maybeBringEmbeddedTaskToForeground(int taskId) {
        if (taskId > 0) {
            // The task in TaskView should be in top to make it visible.
            // NOTE: Tried setTaskAlwaysOnTop before, the flag has some side effect to hinder
            // AccessibilityService from finding the correct window geometry: b/197247311
            mActivityManager.moveTaskToFront(taskId, /* flags= */ 0);
        }
    }
View Code

同時將兩個taskview內嵌後,又單獨處理了各自的生命週期,達到互斥效果

3D桌面跟Launcher通訊

這裏3D桌面需要額外處理,因為3D有個通訊進程,需要監聽底層信號對車模進行同步操作,而由於unity無法監聽到底層信號,所以需要跟launcher進行跨進程通訊

所以在3D處於pause時,需要將通訊進程也暫停,否則信號會一直髮送,並且3D也無法接受信號

override fun setUnityVisible(visible: Boolean) {
            Log.w(TAG, "setUnityVisible:${visible}")
            val fragment = UnityPlayerFragment.Current
                if (fragment != null && fragment.isLoadUnityFinish) {
                    lastVisibleFromLauncher3 = visible
                    Log.w(TAG, "setUnityVisible:setInteractionMsg $visible")
                    if (visible) {
                        fragment.resumeUnityPlayer()
                    } else {
                        fragment.pauseUnityPlayer()
                    }
                }
        }

    }
View Code

跨進程通訊接口

package com.carlauncher;
import android.os.Bundle;
import com.carlauncher.IUnityBridgeCallback;

interface UnityInterface {


    oneway void registerUnityBridgeCallback(IUnityBridgeCallback callback);
    oneway void unregisterUnityBridgeCallback(IUnityBridgeCallback callback);

    /**
     * 通知Unity 交互信息傳遞
     * 交互信息傳輸專用,除Adapter都放這裏  EX:車衣按鈕被點擊 | 天氣信息傳遞(bx1e) | 其他
     *
     * @param msgType 消息類型
     * @param msgData 消息
     */
    oneway void setInteractionMsg(int msgType, in Bundle bundle);


   /**
    * 設置Unity是否處於顯示狀態
    */
    oneway void setUnityVisible(boolean visible);

}
View Code

在service中實現接口,通過setInteractionMsg方法跟unity車模交互通訊

通訊隊列

信號不斷的上報,需要緩存信號然後實時發送同步到3D,這裏需要在子線程中不斷輪詢

public class AutoPullExecutor<K, E> extends Thread {
    private static final String TAG = "AutoPullExecutor";
    private final FilterCache<K, E> mCache;
    private final List<FilterCacheHelper.OnPullCacheCallback<K, E>> mCallbacks;
    private boolean mIsRunning = false;

    public AutoPullExecutor(FilterCache<K, E> cache) {
        mCache = cache;
        mCallbacks = new ArrayList<>();
    }

    @Override
    public void run() {
        Log.d(TAG, "AutoPullExecutor is start");
        mIsRunning = true;
        while (mIsRunning) {
            FilterCache.Node<K, E> node = mCache.poll();

            if (node == null) {
                continue;
            }


            autoPullCallback(node);
        }
    }

    private void autoPullCallback(FilterCache.Node<K, E> node) {
        for (FilterCacheHelper.OnPullCacheCallback<K, E> callback : mCallbacks) {
            callback.onCache(node.key, node.element);
        }
    }

    void addPullCallback(FilterCacheHelper.OnPullCacheCallback<K, E> callback) {
        mCallbacks.add(callback);
    }

    boolean isRunning() {
        return mIsRunning;
    }

    void exit() {
        mIsRunning = false;
        interrupt();
        clear();
    }

    void clear() {
        mCallbacks.clear();
    }
}
View Code

註冊好監聽,需要發送信號時添加到緩存隊列,輪詢判斷是否有需要發送的消息,發送完之後移除緩存

 

user avatar asterlee 头像
点赞 1 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.