Launcher 桌面源码笔记二
<p>车模桌面加载成功后,需要各种交互</p><h4>切换桌面处理</h4>
<p>先补充如何切换桌面,初始化需要指定一个默认桌面,初始化其实两个桌面都会一起加载,假设默认是车模桌面,地图将不会初始化操作,但是地图桌面会内嵌到Launcher中</p>
<p>两个桌面是互斥的,基于这种模式下,就需要隐藏另一个桌面,因为切换动效的缘故,这里直接使用setTranslationX移出屏幕外处理</p>
<p>为了让两个桌面互斥,需要通过 mActivityManager.moveTaskToFront(getTaskId(), 0) 方法让两个taskview内嵌的activity只能一个处于前台,另一个pause</p>
<div class="cnblogs_code"><img id="code_img_closed_f257da9d-85bc-407e-9ce9-819be2b7f310" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_f257da9d-85bc-407e-9ce9-819be2b7f310" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_f257da9d-85bc-407e-9ce9-819be2b7f310" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> maybeBringEmbeddedTaskToForeground(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> taskId) {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (taskId > 0<span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> The task in TaskView should be in top to make it visible.
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> NOTE: Tried setTaskAlwaysOnTop before, the flag has some side effect to hinder
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> AccessibilityService from finding the correct window geometry: b/197247311</span>
mActivityManager.moveTaskToFront(taskId, <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> flags= </span><span style="color: rgba(0, 128, 0, 1)">*/</span> 0<span style="color: rgba(0, 0, 0, 1)">);
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>同时将两个taskview内嵌后,又单独处理了各自的生命周期,达到互斥效果</p>
<h4>3D桌面跟Launcher通讯</h4>
<p>这里3D桌面需要额外处理,因为3D有个通讯进程,需要监听底层信号对车模进行同步操作,而由于unity无法监听到底层信号,所以需要跟launcher进行跨进程通讯</p>
<p>所以在3D处于pause时,需要将通讯进程也暂停,否则信号会一直发送,并且3D也无法接受信号</p>
<div class="cnblogs_code"><img id="code_img_closed_a6ea9216-f32a-4b8a-95c5-96b8a6453d47" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_a6ea9216-f32a-4b8a-95c5-96b8a6453d47" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_a6ea9216-f32a-4b8a-95c5-96b8a6453d47" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">override fun setUnityVisible(visible: Boolean) {
Log.w(TAG, </span>"setUnityVisible:${visible}"<span style="color: rgba(0, 0, 0, 1)">)
val fragment </span>=<span style="color: rgba(0, 0, 0, 1)"> UnityPlayerFragment.Current
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (fragment != <span style="color: rgba(0, 0, 255, 1)">null</span> &&<span style="color: rgba(0, 0, 0, 1)"> fragment.isLoadUnityFinish) {
lastVisibleFromLauncher3 </span>=<span style="color: rgba(0, 0, 0, 1)"> visible
Log.w(TAG, </span>"setUnityVisible:setInteractionMsg $visible"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (visible) {
fragment.resumeUnityPlayer()
} </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
fragment.pauseUnityPlayer()
}
}
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>跨进程通讯接口</p>
<div class="cnblogs_code"><img id="code_img_closed_e2a50d1e-baf6-421d-9396-0f7a4014981f" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_e2a50d1e-baf6-421d-9396-0f7a4014981f" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_e2a50d1e-baf6-421d-9396-0f7a4014981f" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">package</span><span style="color: rgba(0, 0, 0, 1)"> com.carlauncher;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> android.os.Bundle;
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> com.carlauncher.IUnityBridgeCallback;
</span><span style="color: rgba(0, 0, 255, 1)">interface</span><span style="color: rgba(0, 0, 0, 1)"> UnityInterface {
oneway </span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> registerUnityBridgeCallback(IUnityBridgeCallback callback);
oneway </span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> unregisterUnityBridgeCallback(IUnityBridgeCallback callback);
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 通知Unity 交互信息传递
* 交互信息传输专用,除Adapter都放这里EX:车衣按钮被点击 | 天气信息传递(bx1e) | 其他
*
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> msgType 消息类型
* </span><span style="color: rgba(128, 128, 128, 1)">@param</span><span style="color: rgba(0, 128, 0, 1)"> msgData 消息
</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
oneway </span><span style="color: rgba(0, 0, 255, 1)">void</span> setInteractionMsg(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> msgType, in Bundle bundle);
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
* 设置Unity是否处于显示状态
</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
oneway </span><span style="color: rgba(0, 0, 255, 1)">void</span> setUnityVisible(<span style="color: rgba(0, 0, 255, 1)">boolean</span><span style="color: rgba(0, 0, 0, 1)"> visible);
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>在service中实现接口,通过setInteractionMsg方法跟unity车模交互通讯</p>
<h5>通讯队列</h5>
<p>信号不断的上报,需要缓存信号然后实时发送同步到3D,这里需要在子线程中不断轮询</p>
<div class="cnblogs_code"><img id="code_img_closed_5c9136c5-5020-4ee0-8b8b-c8af8f02a912" class="code_img_closed lazyload" data-src="http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif"><img id="code_img_opened_5c9136c5-5020-4ee0-8b8b-c8af8f02a912" class="code_img_opened lazyload" style="display: none" data-src="http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif">
<div id="cnblogs_code_open_5c9136c5-5020-4ee0-8b8b-c8af8f02a912" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> AutoPullExecutor<K, E> <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> Thread {
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String TAG = "AutoPullExecutor"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">final</span> FilterCache<K, E><span style="color: rgba(0, 0, 0, 1)"> mCache;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">final</span> List<FilterCacheHelper.OnPullCacheCallback<K, E>><span style="color: rgba(0, 0, 0, 1)"> mCallbacks;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">boolean</span> mIsRunning = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">public</span> AutoPullExecutor(FilterCache<K, E><span style="color: rgba(0, 0, 0, 1)"> cache) {
mCache </span>=<span style="color: rgba(0, 0, 0, 1)"> cache;
mCallbacks </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> ArrayList<><span style="color: rgba(0, 0, 0, 1)">();
}
@Override
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> run() {
Log.d(TAG, </span>"AutoPullExecutor is start"<span style="color: rgba(0, 0, 0, 1)">);
mIsRunning </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">while</span><span style="color: rgba(0, 0, 0, 1)"> (mIsRunning) {
FilterCache.Node</span><K, E> node =<span style="color: rgba(0, 0, 0, 1)"> mCache.poll();
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (node == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">) {
</span><span style="color: rgba(0, 0, 255, 1)">continue</span><span style="color: rgba(0, 0, 0, 1)">;
}
autoPullCallback(node);
}
}
</span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> autoPullCallback(FilterCache.Node<K, E><span style="color: rgba(0, 0, 0, 1)"> node) {
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (FilterCacheHelper.OnPullCacheCallback<K, E><span style="color: rgba(0, 0, 0, 1)"> callback : mCallbacks) {
callback.onCache(node.key, node.element);
}
}
</span><span style="color: rgba(0, 0, 255, 1)">void</span> addPullCallback(FilterCacheHelper.OnPullCacheCallback<K, E><span style="color: rgba(0, 0, 0, 1)"> callback) {
mCallbacks.add(callback);
}
</span><span style="color: rgba(0, 0, 255, 1)">boolean</span><span style="color: rgba(0, 0, 0, 1)"> isRunning() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> mIsRunning;
}
</span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> exit() {
mIsRunning </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
interrupt();
clear();
}
</span><span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> clear() {
mCallbacks.clear();
}
}</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>注册好监听,需要发送信号时添加到缓存队列,轮询判断是否有需要发送的消息,发送完之后移除缓存</p>
<p> </p><br><br>
来源:https://www.cnblogs.com/LiuZhen/p/19168360
頁:
[1]