新增snapshot多线程执行
This commit is contained in:
@@ -78,7 +78,7 @@ class BaseDrawer {
|
||||
* @param msg
|
||||
* @param data
|
||||
*/
|
||||
protected void sendMessage( int msg, Object data ) {
|
||||
public void sendMessage( int msg, Object data ) {
|
||||
if ( mWorkThreadHandler == null ) {
|
||||
initWorkThreadHandler();
|
||||
}
|
||||
@@ -94,7 +94,7 @@ class BaseDrawer {
|
||||
* @param type
|
||||
* @return
|
||||
*/
|
||||
protected boolean isCarType( int type ) {
|
||||
public boolean isCarType( int type ) {
|
||||
AdasRecognizedType recognizedType = AdasRecognizedType.valueFrom( type );
|
||||
if ( recognizedType == AdasRecognizedType.classIdCar
|
||||
|| recognizedType == AdasRecognizedType.classIdTrafficBus
|
||||
@@ -115,7 +115,7 @@ class BaseDrawer {
|
||||
* @param speed
|
||||
* @param isVrMode
|
||||
*/
|
||||
protected void showSelfSpeed( Context context, IMogoMarker mogoMarker, double speed, boolean isVrMode ) {
|
||||
public void showSelfSpeed( Context context, IMogoMarker mogoMarker, double speed, boolean isVrMode ) {
|
||||
if ( mogoMarker == null || mogoMarker.isDestroyed() ) {
|
||||
return;
|
||||
}
|
||||
@@ -189,7 +189,7 @@ class BaseDrawer {
|
||||
* @param isRtk
|
||||
* @return
|
||||
*/
|
||||
protected double[] matchRoad( double lon, double lat, double angle, boolean isRtk ) {
|
||||
public double[] matchRoad( double lon, double lat, double angle, boolean isRtk ) {
|
||||
return MogoApisHandler.getInstance()
|
||||
.getApis()
|
||||
.getMapServiceApi()
|
||||
@@ -206,7 +206,7 @@ class BaseDrawer {
|
||||
* @param curSatelliteTime
|
||||
* @return
|
||||
*/
|
||||
protected long computeAnimDuration( long lastSystemTime, long curSystemTime, long lastSatelliteTime, long curSatelliteTime ) {
|
||||
public long computeAnimDuration( long lastSystemTime, long curSystemTime, long lastSatelliteTime, long curSatelliteTime ) {
|
||||
long systemTimeInterval = curSystemTime - lastSystemTime - 25;
|
||||
long satelliteTimeInterval = curSatelliteTime - lastSatelliteTime - 25;
|
||||
long interval = systemTimeInterval < satelliteTimeInterval || satelliteTimeInterval == 0 ? systemTimeInterval : satelliteTimeInterval;
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.mogo.module.common.drawer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
@@ -16,6 +17,7 @@ import com.mogo.module.common.R;
|
||||
import com.mogo.module.common.api.CallChatApi;
|
||||
import com.mogo.module.common.constants.DataTypes;
|
||||
import com.mogo.module.common.kt.ScopeManager;
|
||||
import com.mogo.module.common.utils.SimpleHandlerThreadPool;
|
||||
import com.mogo.realtime.entity.CloudRoadData;
|
||||
import com.mogo.realtime.entity.MogoSnapshotSetData;
|
||||
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
|
||||
@@ -129,6 +131,8 @@ public class SnapshotSetDataDrawer extends BaseDrawer implements IMogoMarkerClic
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<String,String> cloudKeyCache = new ArrayMap<>();
|
||||
|
||||
/**
|
||||
* mogo 他车、mogo 他车识别的社会车辆、路边单元识别的车辆
|
||||
*
|
||||
@@ -142,29 +146,24 @@ public class SnapshotSetDataDrawer extends BaseDrawer implements IMogoMarkerClic
|
||||
|
||||
List< CloudRoadData > allDatumsList = new ArrayList<>();
|
||||
prepareData( data.getAllList(), allDatumsList );
|
||||
Map< String, IMogoMarker > newAdasRecognizedMarkersCaches = new ConcurrentHashMap<>();
|
||||
Map< String, String > newAdasRecognizedMarkersCaches = new ArrayMap<>(allDatumsList.size());
|
||||
for ( CloudRoadData cloudRoadData : allDatumsList ) {
|
||||
|
||||
// double[] matchedPoint = matchRoad( cloudRoadData.getLon(),
|
||||
// cloudRoadData.getLat(),
|
||||
// cloudRoadData.getHeading(),
|
||||
// true
|
||||
// );
|
||||
// if ( matchedPoint != null ) {
|
||||
// cloudRoadData.setLon( matchedPoint[0] );
|
||||
// cloudRoadData.setLat( matchedPoint[1] );
|
||||
// }
|
||||
ScopeManager.INSTANCE.mainScope( () -> {
|
||||
rendCarOneFrame( cloudRoadData, newAdasRecognizedMarkersCaches );
|
||||
} );
|
||||
cloudKeyCache.remove(cloudRoadData.getUniqueKey());
|
||||
// newAdasRecognizedMarkersCaches.put(cloudRoadData.getUniqueKey(), cloudRoadData.getUniqueKey());
|
||||
SimpleHandlerThreadPool.getInstance().post(cloudRoadData);
|
||||
// ScopeManager.INSTANCE.mainScope( () -> {
|
||||
// rendCarOneFrame( cloudRoadData, newAdasRecognizedMarkersCaches );
|
||||
// } );
|
||||
}
|
||||
ScopeManager.INSTANCE.mainScope( () -> {
|
||||
sendMessage( MSG_REMOVE_DIRTY_MARKERS, mCloudSnapshotMarkersCaches );
|
||||
mCloudSnapshotMarkersCaches = newAdasRecognizedMarkersCaches;
|
||||
} );
|
||||
SimpleHandlerThreadPool.getInstance().removeDirtyMarker(cloudKeyCache.values());
|
||||
cloudKeyCache = newAdasRecognizedMarkersCaches;
|
||||
// ScopeManager.INSTANCE.mainScope( () -> {
|
||||
// sendMessage( MSG_REMOVE_DIRTY_MARKERS, mCloudSnapshotMarkersCaches );
|
||||
// mCloudSnapshotMarkersCaches = newAdasRecognizedMarkersCaches;
|
||||
// } );
|
||||
}
|
||||
|
||||
private void rendCarOneFrame( CloudRoadData cloudRoadData, Map< String, IMogoMarker > newAdasRecognizedMarkersCaches ) {
|
||||
public void rendCarOneFrame( CloudRoadData cloudRoadData, Map< String, IMogoMarker > newAdasRecognizedMarkersCaches ) {
|
||||
|
||||
if ( cloudRoadData == null ) {
|
||||
return;
|
||||
@@ -196,8 +195,9 @@ public class SnapshotSetDataDrawer extends BaseDrawer implements IMogoMarkerClic
|
||||
bindClickListener( marker );
|
||||
}
|
||||
}
|
||||
|
||||
newAdasRecognizedMarkersCaches.put( uniqueKey, marker );
|
||||
if(newAdasRecognizedMarkersCaches != null) {
|
||||
newAdasRecognizedMarkersCaches.put(uniqueKey, marker);
|
||||
}
|
||||
//
|
||||
// if ( mChangeCarModeStatus ) {
|
||||
// mIsVrMode = MogoApisHandler.getInstance().getApis().getStatusManagerApi().isVrMode();
|
||||
@@ -263,7 +263,7 @@ public class SnapshotSetDataDrawer extends BaseDrawer implements IMogoMarkerClic
|
||||
/**
|
||||
* 绑定点击事件
|
||||
*/
|
||||
private void bindClickListener( IMogoMarker marker ) {
|
||||
public void bindClickListener( IMogoMarker marker ) {
|
||||
if ( marker == null || marker.isDestroyed() ) {
|
||||
return;
|
||||
}
|
||||
@@ -276,7 +276,7 @@ public class SnapshotSetDataDrawer extends BaseDrawer implements IMogoMarkerClic
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
private IMogoMarker drawSnapshotDataMarker( CloudRoadData data ) {
|
||||
public IMogoMarker drawSnapshotDataMarker( CloudRoadData data ) {
|
||||
if ( data == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
package com.mogo.module.common.utils;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.map.MogoLatLng;
|
||||
import com.mogo.map.marker.IMogoMarker;
|
||||
import com.mogo.module.common.MogoApisHandler;
|
||||
import com.mogo.module.common.drawer.AdasRecognizedResultDrawer;
|
||||
import com.mogo.module.common.drawer.SnapshotSetDataDrawer;
|
||||
import com.mogo.realtime.entity.CloudRoadData;
|
||||
import com.mogo.utils.logger.Logger;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.mogo.module.common.drawer.BaseDrawer.MSG_REMOVE_DIRTY_MARKERS;
|
||||
|
||||
/**
|
||||
* 简单HandlerThread线程池实现
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public class SimpleHandlerThreadPool {
|
||||
private static final String TAG = "SimpleHandlerThreadPool";
|
||||
private HandlerThread renderThread = new HandlerThread("one-frame-render-thread");
|
||||
private Handler renderHandler;
|
||||
private SimpleHandlerThreadPool() {
|
||||
renderThread.start();
|
||||
renderHandler = new Handler(renderThread.getLooper());
|
||||
}
|
||||
|
||||
private static final SimpleHandlerThreadPool INSTANCE = new SimpleHandlerThreadPool();
|
||||
|
||||
public static SimpleHandlerThreadPool getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 默认线程数量
|
||||
*/
|
||||
private static final int DEFAULT_THREAD_COUNT = 3;
|
||||
|
||||
private int threadCount = DEFAULT_THREAD_COUNT;
|
||||
|
||||
public void setThreadCount(int threadCount) {
|
||||
this.threadCount = threadCount;
|
||||
}
|
||||
|
||||
Map<String, WorkHandler> dataHandlerMap = new ArrayMap<>();
|
||||
Map<Integer, WorkHandler> handlerPool = new ArrayMap<>();
|
||||
private int lastUseThreadId = -1;
|
||||
|
||||
public void post(CloudRoadData cloudRoadData) {
|
||||
String uuid = cloudRoadData.getUniqueKey();
|
||||
Message msg;
|
||||
if (dataHandlerMap.containsKey(uuid)) {
|
||||
msg = dataHandlerMap.get(uuid).obtainMessage();
|
||||
} else {
|
||||
if (handlerPool.size() < threadCount) {
|
||||
// 新开线程
|
||||
lastUseThreadId = handlerPool.size();
|
||||
HandlerThread thread = new HandlerThread("one-frame-work-thread-" + handlerPool.size());
|
||||
thread.start();
|
||||
WorkHandler handler = new WorkHandler(thread.getLooper());
|
||||
handlerPool.put(handlerPool.size(), handler);
|
||||
dataHandlerMap.put(uuid, handler);
|
||||
msg = handler.obtainMessage();
|
||||
} else {
|
||||
// 复用线程
|
||||
if (lastUseThreadId == threadCount - 1) {
|
||||
lastUseThreadId = 0;
|
||||
} else {
|
||||
lastUseThreadId++;
|
||||
}
|
||||
WorkHandler handler = handlerPool.get(lastUseThreadId);
|
||||
dataHandlerMap.put(uuid, handler);
|
||||
msg = handler.obtainMessage();
|
||||
}
|
||||
}
|
||||
msg.obj = cloudRoadData;
|
||||
msg.sendToTarget();
|
||||
}
|
||||
|
||||
public void removeDirtyMarker(Collection<String> keys) {
|
||||
for (WorkHandler handler : handlerPool.values()) {
|
||||
handler.removeDirtyMarker(keys);
|
||||
}
|
||||
}
|
||||
|
||||
class WorkHandler extends Handler {
|
||||
public WorkHandler(Looper looper) {
|
||||
super(looper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
CloudRoadData cloudRoadData = (CloudRoadData) msg.obj;
|
||||
rendCarOneFrame(cloudRoadData);
|
||||
}
|
||||
|
||||
private final Map<String, IMogoMarker> markerCache = new ArrayMap<>();
|
||||
private final Map<String, CloudRoadData> roadDataCache = new ArrayMap<>();
|
||||
private final Map<String, Long> lastExecutionTimeCache = new ArrayMap<>();
|
||||
|
||||
private void rendCarOneFrame(CloudRoadData cloudRoadData) {
|
||||
if (cloudRoadData == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 暂时只显示车辆
|
||||
if (TextUtils.isEmpty(cloudRoadData.getSn())) {
|
||||
if (!SnapshotSetDataDrawer.getInstance().isCarType(cloudRoadData.getType())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String uniqueKey = cloudRoadData.getUniqueKey();
|
||||
if (TextUtils.isEmpty(uniqueKey)
|
||||
// 本地过滤重复下发的adas识别车辆
|
||||
|| AdasRecognizedResultDrawer.getInstance().hasCached(uniqueKey)) {
|
||||
return;
|
||||
}
|
||||
IMogoMarker marker = markerCache.get(uniqueKey);
|
||||
CloudRoadData lastPosition = roadDataCache.put(uniqueKey, cloudRoadData);
|
||||
if (marker == null || marker.isDestroyed()) {
|
||||
marker = SnapshotSetDataDrawer.getInstance().drawSnapshotDataMarker(cloudRoadData);
|
||||
if (marker == null) {
|
||||
return;
|
||||
}
|
||||
markerCache.put(uniqueKey, marker);
|
||||
if (!TextUtils.isEmpty(cloudRoadData.getSn())) {
|
||||
SnapshotSetDataDrawer.getInstance().bindClickListener(marker);
|
||||
}
|
||||
}
|
||||
|
||||
if(cloudRoadData.getFromType() == CloudRoadData.FROM_MY_LOCATION) {
|
||||
|
||||
double[] matchedPoint = SnapshotSetDataDrawer.getInstance().matchRoad(cloudRoadData.getLon(),
|
||||
cloudRoadData.getLat(),
|
||||
cloudRoadData.getHeading(),
|
||||
true
|
||||
);
|
||||
if (matchedPoint != null) {
|
||||
cloudRoadData.setLon(matchedPoint[0]);
|
||||
cloudRoadData.setLat(matchedPoint[1]);
|
||||
}
|
||||
}
|
||||
|
||||
final IMogoMarker finalMarker = marker;
|
||||
Logger.d(TAG, "work in " + Thread.currentThread().getName());
|
||||
renderHandler.post(()->{
|
||||
// 由于地图现在不支持addDynamicAnchorPosition并发,所以工作线程仅做相关计算,真正绘制发送到另外一条绘制线程中做
|
||||
if (lastPosition != null && !lastPosition.equals(cloudRoadData)) {
|
||||
long interval = SnapshotSetDataDrawer.getInstance().computeAnimDuration(lastPosition.getSystemTime(), cloudRoadData.getSystemTime(), lastPosition.getSatelliteTime(), cloudRoadData.getSatelliteTime());
|
||||
interval = SystemClock.uptimeMillis() - lastExecutionTimeCache.get(uniqueKey);
|
||||
finalMarker.addDynamicAnchorPosition(new MogoLatLng(cloudRoadData.getLat(), cloudRoadData.getLon()), interval);
|
||||
Logger.d(TAG, "anim duration: %s in thread: %s", interval, Thread.currentThread().getName());
|
||||
} else {
|
||||
finalMarker.setRotateAngle((float) cloudRoadData.getHeading());
|
||||
finalMarker.setPosition(cloudRoadData.getLat(), cloudRoadData.getLon());
|
||||
Logger.d(TAG, "设置点位置 in thread: %s", Thread.currentThread().getName());
|
||||
}
|
||||
lastExecutionTimeCache.put(uniqueKey, SystemClock.uptimeMillis());
|
||||
SnapshotSetDataDrawer.getInstance().showSelfSpeed(AbsMogoApplication.getApp(), finalMarker, cloudRoadData.getSpeed(), MogoApisHandler.getInstance().getApis().getStatusManagerApi().isVrMode());
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void removeDirtyMarker(Collection<String> keys) {
|
||||
Map<String, IMogoMarker> result = new ArrayMap<>(keys.size());
|
||||
for (String key : keys) {
|
||||
if(markerCache.containsKey(key)) {
|
||||
result.put(key, markerCache.remove(key));
|
||||
}
|
||||
}
|
||||
SnapshotSetDataDrawer.getInstance().sendMessage( MSG_REMOVE_DIRTY_MARKERS, result );
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user