我现在真的很沮丧。
我尝试进行套接字连接,但我总是遇到NetworkOnMainThread异常。
我的目标是创建一个具有线程,套接字和Messenger模型的对象,以便专门使用该对象进行通信,如下所示:
WebBridge wb = new WebBridge();
wb.Send("My data to send", myLocalMessengerForAnswer);
我尝试使用具有相同结果的Handler。我也试过这个,用自己的Handler创建自己的线程,但没有成功。
Aren的处理程序是否拥有自己的Thread?如果我应该在Handler的线程中,为什么我会收到NetworkInMainThread异常?
提前致谢。
public class WebBridge {
private class WebBridgeThread extends Thread {
static final int STARTUP = 1;
public Handler handler;
Socket socket;
public WebBridgeThread() {
super("WebBridgeThread");
}
@Override
public void run() {
Looper.prepare();
handler = new Handler() {
@Override
public void dispatchMessage(Message msg) {
// TODO Auto-generated method stub
super.dispatchMessage(msg);
switch(msg.what) {
case STARTUP:
try {
socket = new Socket("192.168.100.99",1234);
int fer = 5;
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
};
Looper.loop();
}
}
public WebBridge(Context paramContext) {
WebBridgeThread wbt = new WebBridgeThread();
wbt.start();
Message msg = new Message();
msg.what = WebBridgeThread.STARTUP;
wbt.handler.dispatchMessage(msg);
}
答案 0 :(得分:3)
如果我应该在Handler的线程中,为什么我会收到NetworkInMainThread异常?
如果您检查public class PlacesMapActivity extends MapActivity {
PlacesList nearPlaces;
MapView mapView;
List<Overlay> mapOverlays;
AddItemizedOverlay itemizedOverlay;
GeoPoint geoPoint;
MapController mc;
double latitude;
double longitude;
OverlayItem overlayitem;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_places_map);
Intent i = getIntent();
String user_latitude = i.getStringExtra("user_latitude");
String user_longitude = i.getStringExtra("user_longitude");
nearPlaces = (PlacesList) i.getSerializableExtra("near_places");
mapView = (MapView) findViewById(R.id.mapView);
mapView.setBuiltInZoomControls(true);
mapOverlays = mapView.getOverlays();
geoPoint = new GeoPoint((int) (Double.parseDouble(user_latitude) * 1E6),
(int) (Double.parseDouble(user_longitude) * 1E6));
Drawable drawable_user = this.getResources()
.getDrawable(R.drawable.mark_red);
itemizedOverlay = new AddItemizedOverlay(drawable_user, this);
overlayitem = new OverlayItem(geoPoint, "Your Location",
"That is you!");
itemizedOverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedOverlay);
itemizedOverlay.populateNow();
Drawable drawable = this.getResources()
.getDrawable(R.drawable.mark_blue);
itemizedOverlay = new AddItemizedOverlay(drawable, this);
mc = mapView.getController();
int minLat = Integer.MAX_VALUE;
int minLong = Integer.MAX_VALUE;
int maxLat = Integer.MIN_VALUE;
int maxLong = Integer.MIN_VALUE;
if (nearPlaces.results != null) {
// loop through all the places
for (Place place : nearPlaces.results) {
latitude = place.geometry.location.lat; // latitude
longitude = place.geometry.location.lng; // longitude
geoPoint = new GeoPoint((int) (latitude * 1E6),
(int) (longitude * 1E6));
overlayitem = new OverlayItem(geoPoint, place.name,
place.vicinity);
itemizedOverlay.addOverlay(overlayitem);
// calculating map boundary area
minLat = (int) Math.min( geoPoint.getLatitudeE6(), minLat );
minLong = (int) Math.min( geoPoint.getLongitudeE6(), minLong);
maxLat = (int) Math.max( geoPoint.getLatitudeE6(), maxLat );
maxLong = (int) Math.max( geoPoint.getLongitudeE6(), maxLong );
}
mapOverlays.add(itemizedOverlay);
// showing all overlay items
itemizedOverlay.populateNow();
}
mapView.getController().zoomToSpan(Math.abs( minLat - maxLat ), Math.abs( minLong - maxLong ));
mc.animateTo(new GeoPoint((maxLat + minLat)/2, (maxLong + minLong)/2 ));
mapView.postInvalidate();
}
@Override
protected boolean isRouteDisplayed() {
return false;
}
}
的代码,您会看到Handler
基本上调用dispatchMessage()
,这意味着它会在当前线程上运行,即您的案例中的UI线程。
相反,如果你调用handleMessage()
,处理程序会将消息排入队列并使用looper在线程上运行sendMessage()
中的逻辑,即你的情况下的后台线程。 (在队列handleMessage()
之后直接调用队列中的消息后调用Looper.loop()
;这里当前线程是带有looper的线程)
所以你需要:
dispatchMessage()
中的sendMessage()
代替WebBridge()
dispatchMessage()
handleMessage()
而不是dispatchMessage()
醇>
将线程优先级设置为后台也是一个好主意,所以你不会在UI线程中赢得这么多。
顺便说一句,您还可以使用Handler
为您完成艰苦的工作,它会创建一个新线程并设置其优先级。然后,在启动之后,您可以获取其looper(HandlerThread
)并将其推送到处理程序的构造函数中。您仍然需要在网络逻辑的处理程序中覆盖getLooper()
。