Android EventBus不在主线程上
我试图从我的WS中获取位置,并在我的Google地图片段中更新我的标记,因此我正在做的是: 我有我的HomeActivity,它包含2个片段,2个谷歌地图,其中一个有TileOverlay 在我的GoogleMap片段中,我试图从OnCamerachenglistener获取标记位置,以便在用户继续移动时添加标记 我正在使用EventBus和Okhttp进行异步请求 我的谷歌地图片段:Android EventBus不在主线程上,android,google-maps,android-fragments,greenrobot-eventbus,Android,Google Maps,Android Fragments,Greenrobot Eventbus,我试图从我的WS中获取位置,并在我的Google地图片段中更新我的标记,因此我正在做的是: 我有我的HomeActivity,它包含2个片段,2个谷歌地图,其中一个有TileOverlay 在我的GoogleMap片段中,我试图从OnCamerachenglistener获取标记位置,以便在用户继续移动时添加标记 我正在使用EventBus和Okhttp进行异步请求 我的谷歌地图片段: public class GoogleMapFragment extends FragmentBase {
public class GoogleMapFragment extends FragmentBase {
@Override
public void onResume() {
mapView.onResume();
BusHelper.register(this); // Register the EventBus with my helper
super.onResume();
}
@Override
public void onPause() {
BusHelper.unregister(this); // Unregister the EventBus with my helper
super.onPause();
}
public GoogleMap.OnCameraChangeListener getCameraChangeListener() {
return new GoogleMap.OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition cameraPosition) {
//those are corners of visible region
VisibleRegion visibleRegion = mMap.getProjection().getVisibleRegion();
LatLng farLeft = visibleRegion.farLeft;
LatLng farRight = visibleRegion.farRight;
LatLng nearLeft = visibleRegion.nearLeft;
LatLng nearRight = visibleRegion.nearRight;
double minY = nearLeft.latitude;
double minX = nearLeft.longitude;
double maxY = farRight.latitude;
double maxX = farRight.longitude;
//Send the WS Request to a manager who uses okhttp
ApiManager.getPositions(minX, minY, maxX, maxY);
}
};
}
//Receive the eventBus event
public void onEvent(GetPositionsEvent event) {
if (event.positions != null)
setMarkersByVisibleRegion(event.positions);
}
在此之后,它将在APIManager中执行WS请求
public class IMSApiManager {
private final static Gson gson = new Gson();
private static Positions mPositions;
/**
* @return Positions
*/
public static void getPositions(double minX, double minY, double maxX, double maxY) {
String TAG = "getPositions";
String wSRequest = AppConstants.REQUEST_POSITIONS
.replace("{vUser}", "CARREPH1")
.replace("{vMinX}", new BigDecimal(minX).toPlainString())
.replace("{vMinY}", new BigDecimal(minY).toPlainString())
.replace("{vMaxX}", new BigDecimal(maxX).toPlainString())
.replace("{vMaxY}", new BigDecimal(maxY).toPlainString());
try {
RestAsyncHttpClient.doGetRequest(wSRequest, new GetPositionsCallback() {
@Override
public void onFailure(Request request, IOException e) {
super.onFailure(request, e);
}
@Override
public void onResponse(Response response) throws IOException {
super.onResponse(response);
mPositions = gson.fromJson(response.body().charStream(), Positions.class);
BusHelper.post(new GetPositionsEvent(mPositions)); //Post the eventBus
}
});
} catch (IOException exp) {
LogHelper.error(TAG, "Error getting positions", exp);
}
}
}
我熟悉非主线程错误,但在理论上这是可能的,如果不是的话,我如何在不执行片段的新实例的情况下添加标记。当您尝试在后台线程中将对象发布到EventBus时,会出现错误。解决办法是,如果发布。。。在后台线程中调用,让处理程序将其移动到主线程 超越你的丛林人的岗位。。。方法并执行以下操作
public class BusHelper extends Bus {
...
private final Handler mHandler = new Handler(Looper.getMainLooper());
@Override
public void post(final Object event) {
if (Looper.myLooper() == Looper.getMainLooper()) {
super.post(event);
} else {
mHandler.post(new Runnable() {
@Override
public void run() {
BusHelper.super.post(event);
}
});
}
}
...
}
希望这有帮助。当您尝试在后台线程中将对象发布到EventBus时,会出现错误。解决办法是,如果发布。。。在后台线程中调用,让处理程序将其移动到主线程 超越你的丛林人的岗位。。。方法并执行以下操作
public class BusHelper extends Bus {
...
private final Handler mHandler = new Handler(Looper.getMainLooper());
@Override
public void post(final Object event) {
if (Looper.myLooper() == Looper.getMainLooper()) {
super.post(event);
} else {
mHandler.post(new Runnable() {
@Override
public void run() {
BusHelper.super.post(event);
}
});
}
}
...
}
希望这有帮助。只需使用onEventMainThread而不是OneEvent。它也解决了我的问题
// Called in Android UI's main thread
public void onEventMainThread(MessageEvent event) {
textField.setText(event.message);
}
为什么??
由于在同一线程中调用了OneEvent,因此需要在主线程上运行代码。只需使用OneEventMainThread而不是OneEvent。它也解决了我的问题
// Called in Android UI's main thread
public void onEventMainThread(MessageEvent event) {
textField.setText(event.message);
}
为什么??
由于OneEvent是在同一线程中调用的,因此您需要在主线程上运行代码。后台线程成功后,您可以在eventbus对象上调用post。post的参数是任何类的对象,因此根据您的需求设计一个自定义类,该类将保存后台线程的结果 现在,对于需要完成UI工作的活动,只需定义:
public void onEventMainThread(final CobbocEvent event)
{
if (event.getType() == CobbocEvent.POSITION)
{ //If background work is success
if (event.getStatus())
{
//Do UI Stuff on main thread
}
}
}
CobboEvent是用于存储后台线程结果数据的自定义类:
public class CobbocEvent{
public CobbocEvent(int type) {
this(type, true, null);
}
public CobbocEvent(int type, boolean status) {
this(type, status, null);
}
public CobbocEvent(int type, boolean status, Object value) {
TYPE = type;
STATUS = status;
VALUE = value;
}
public CobbocEvent(int type, boolean status, int value) {
TYPE = type;
STATUS = status;
VALUE = value;
}
....
我相信您已经明白了这一点:当后台线程成功时,您可以调用eventbus对象上的post。post的参数是任何类的对象,因此根据您的需求设计一个自定义类,该类将保存后台线程的结果 现在,对于需要完成UI工作的活动,只需定义:
public void onEventMainThread(final CobbocEvent event)
{
if (event.getType() == CobbocEvent.POSITION)
{ //If background work is success
if (event.getStatus())
{
//Do UI Stuff on main thread
}
}
}
CobboEvent是用于存储后台线程结果数据的自定义类:
public class CobbocEvent{
public CobbocEvent(int type) {
this(type, true, null);
}
public CobbocEvent(int type, boolean status) {
this(type, status, null);
}
public CobbocEvent(int type, boolean status, Object value) {
TYPE = type;
STATUS = status;
VALUE = value;
}
public CobbocEvent(int type, boolean status, int value) {
TYPE = type;
STATUS = status;
VALUE = value;
}
....
我相信您已经明白了这一点:接受的答案仅适用于低于第三版的版本,对于其他版本,您应该使用threadMode=threadMode.MAIN
Accepted answer仅适用于低于Threed的版本,对于其他版本,应使用threadMode=threadMode.MAIN
这是有道理的,但是通过eventBus文档,我能够捕捉到这样的背景事件!//在后台线程public void onEventBackgroundThreadMessageEvent事件{saveToDiskevent.message;}中调用。我假设在您的snipet中,MainBus是我的EventBus super类实例,但EventBus没有super,因此我无法完成它,但是通过eventBus文档,我能够捕捉到这样的背景事件!//在后台线程public void onEventBackgroundThreadMessageEvent事件{saveToDiskevent.message;}中调用。我假设在您的snipet中,MainBus是我的EventBus超类实例,但是EventBus没有super所以我无法完成但是@Pedro我的帖子它不是来自主线程它是一个okhttp后台线程所以它不可能在我之前的评论中,我尝试过并运行了!但从eventBus文档中,我了解到OneEvent是对OneEventMainThread的一种短路,但我错了,你是对的。这应该是正确的答案,我将删除我以前的答案,并将这一个标记为正确。葡萄牙语是一种非语言:是一种语言;我认为默认情况下,这个方法应该在库中使用。但是我不能做任何非常重要的事情来改变这个规则。如果你认为Java应用程序不是Android应用程序以不同于Android的方式运行,这是有道理的。但是@Pedro my Post它不是来自主线程,它是一个okhttp后台线程,所以它不可能。在我之前的评论中,我试过了,它运行了!但从eventBus文档中,我了解到OneEvent是对OneEventMainThread的一种短路,但我错了,你是对的。这应该是正确的答案,我将删除我以前的答案,并将这一个标记为正确。葡萄牙语是一种非语言:是一种语言;我认为默认情况下,这个方法应该在库中使用。但是我不能做任何非常重要的事情来改变这个规则。如果你认为Java应用程序而不是Android应用程序在不同的环境中运行
租用Android的方式,这是有意义的。是的,这是我所做的,我不确定性能,但周一我将进行一些测试。如果您发现在设备上处理服务器数据的更有效方法,请与我们分享。这是我所做的,我不确定性能,但周一我将运行一些测试。如果您发现在设备上处理服务器数据的更有效方法,请务必共享。这是正确的答案,因为您可以选择希望事件处理程序位于哪个线程上。这里的文档:这是针对EventBus版本3的文档,它基于注释。虽然这个答案是正确的,但对于以下任何版本,接受的答案也是正确的。这是正确的答案,因为您可以选择希望事件处理程序处于哪个线程上。这里的文档:这是针对EventBus版本3的文档,它基于注释。虽然这个答案是正确的,但对于以下任何版本,公认的答案也是正确的。