发送HTTP请求,程序卡住,求支招

XuanrenLu 2015-05-27 09:43:36
用httpclient发送请求:HttpResponse response = client.execute(httpPost);
(在测试断网的情况下,程序的情况)
超时的时间设为5秒。发送http请求的代码放在一个用bindservice启动的一个Service里面,在超时的5秒的时间内,UI线程是卡住的,求支招
...全文
675 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
李元静 2015-05-28
  • 打赏
  • 举报
回复
3楼正解,asynctask只适合几秒的任务,不适合长时间的网络任务。
budworm 2015-05-28
  • 打赏
  • 举报
回复
用 AsyncHttpClient,异步的。
bj100 2015-05-28
  • 打赏
  • 举报
回复
用 AsyncHttpClient,异步的。
navalphantom 2015-05-28
  • 打赏
  • 举报
回复
引用 11 楼 lxr0724 的回复:
[quote=引用 4 楼 shanwu1985 的回复:] 连网, File IO等这类型耗时操作,最好是采用线程池来操作。
是放在线程池执行的[/quote] 我觉得这个时候 Log.d() 是你最好的朋友…你可以多打一些 log 看看是哪边卡住了 或是比较花时间 :)
XuanrenLu 2015-05-28
  • 打赏
  • 举报
回复
引用 4 楼 shanwu1985 的回复:
连网, File IO等这类型耗时操作,最好是采用线程池来操作。
是放在线程池执行的
XuanrenLu 2015-05-28
  • 打赏
  • 举报
回复
@Override
		public void run() {
                        // 这是Service里面开启的线程
			if (((BoCaiApplication)(getApplication())).getAcitivityFuncState()) {
				BoCaiApplication application = ((BoCaiApplication)getApplication());
				int oldGridX = application.getOldGridx();
				int oldGridY = application.getOldGridy();
				UserPositionItem item = application.getUserPositionItem();
				// 用户跳出当前网格,则向服务器更新
				if (/*!((oldGridX == item.gridX) && (oldGridY == item.gridY))*/true) {
					try {
						list = UserPositionService.getUserPositions(oldGridX, oldGridY, item);
						Log.v("bug", "list 装载完毕");
						// 判断人数是否足以发布活动
						if (list != null) {
							if (AutoPublishTool.canAutoPublish(list, item)) {
								// 弹出对话框,询问是否发布聚集
								if (((BoCaiApplication)(getApplication())).canDisplayPublishDialog()) {
									handlerMsg.sendEmptyMessage(IMessage.OpenDialog);
								}
							}else {
								Log.v("bug", "人数不足");
							}
						}else {
							Log.v("bug", "list 为 空");
						}
					} catch (InterruptedException|ExecutionException|IOException e) {
							Log.v("bug", "请求位置信息时,连接服务器超时(Position Service)");
							handler.sendEmptyMessage(IMessage.Connect_server_Failed_Int);
					} 
				}
			}
			
			
			if (isServiceRunning) {
				handler.postDelayed(this, spanTime);
			}
		}
public class UserPositionService {

	/**
	 * 向服务器更新位置信息并当前的网格 根据网格坐标,返回周围9个网格的用户位置(POST发请求)
	 * 
	 * @param oldGridX
	 *            过时的网格坐标x
	 * @param oldGridY
	 *            过时的网格坐标y
	 * @param item
	 *            用户当前的位置信息
	 * @return 当前用户周围的用户位置信息的集合
	 */
	public static ArrayList<UserPositionItem> getUserPositions(int oldGridX,
			int oldGridY, UserPositionItem item)
			throws  InterruptedException,
			ExecutionException,IOException {

		// 向服务器请求聚集信息
		ExecutorService threadpool = Executors.newSingleThreadExecutor();
		Future<ArrayList<UserPositionItem>> future = threadpool
				.submit(new MyCallable(oldGridX, oldGridY, item));
		Log.v("bug", "已发送请求");
		return future.get();

	}

	private static class MyCallable implements
			Callable<ArrayList<UserPositionItem>> {
		private int oldGridX;
		private int oldGridY;
		private UserPositionItem item;

		public MyCallable(int oldGridX, int oldGridY, UserPositionItem item) {
			super();
			this.oldGridX = oldGridX;
			this.oldGridY = oldGridY;
			this.item = item;
		}

		@Override
		public ArrayList<UserPositionItem> call()
				throws IOException {
			return UserPositionService
					.getUserPosition(oldGridX, oldGridY, item);

		}

	}

	/**
	 * 向服务器更新位置信息并当前的网格 根据网格坐标,返回周围9个网格的用户位置(POST发请求)
	 * 
	 * @param oldGridX
	 *            过时的网格坐标x
	 * @param oldGridY
	 *            过时的网格坐标y
	 * @param item
	 *            用户当前的位置信息
	 * @return 当前用户周围的用户位置信息的集合
	 * @throws IOException 
	 */
	private static ArrayList<UserPositionItem> getUserPosition(int oldGridX,
			int oldGridY, UserPositionItem item) throws IOException {
		ArrayList<UserPositionItem> list;
		String path = "http://" + ServerIp.localhost
				+ ":8080/AndroidSever/UserPositionServlet";
		try {
			HttpClient client = new DefaultHttpClient();
			HttpPost httpPost = new HttpPost(path);
			List<NameValuePair> parameters = new ArrayList<NameValuePair>();
			parameters.add(new BasicNameValuePair(IPosition.Old_Grid_x,
					oldGridX + ""));
			parameters.add(new BasicNameValuePair(IPosition.Old_Grid_y,
					oldGridY + ""));
			parameters
					.add(new BasicNameValuePair(IPosition.UserId, item.userId));
			parameters.add(new BasicNameValuePair(IPosition.Grid_x, item.gridX
					+ ""));
			parameters.add(new BasicNameValuePair(IPosition.Grid_y, item.gridY
					+ ""));
			parameters.add(new BasicNameValuePair(IPosition.Latitude,
					item.latitude + ""));
			parameters.add(new BasicNameValuePair(IPosition.Longitude,
					item.longitude + ""));
			httpPost.setEntity(new UrlEncodedFormEntity(parameters, "UTF-8"));
			//Represents a collection of HTTP protocol and framework parameters  
            HttpParams params = null;  
            params = client.getParams();  
            //set timeout  
            HttpConnectionParams.setConnectionTimeout(params, 5000);  
            HttpConnectionParams.setSoTimeout(params, 35000);  
			HttpResponse response = client.execute(httpPost);

			int code = response.getStatusLine().getStatusCode();
			Log.v("bug", "UserPositionService code = " + code);
			// 连接成功,返回信息
			if (code == 200) {
				InputStream is = response.getEntity().getContent();
				list = parseJSON(is);
				return list;
			} else {
				Log.v("bug", "code !=200,list = null");
				return null;
			}
		} catch (ConnectTimeoutException e) {
			Log.v("bug", "ConnectTimeoutException 请求位置信息时,连接服务器超时(Service)");
			throw e;
		} catch (IOException e) {
			Log.v("bug", "IOException 请求位置信息时,连接服务器超时(Service)");
			return null;
		} catch (Exception e) {
			Log.v("bug", "Exception 请求位置信息时,连接服务器超时(Service)");
			return null;
		}
	}

	/**
	 * 将JSON格式的流转换为list对象集合
	 * 
	 * @param is
	 * @return
	 * @throws Exception
	 */
	private static ArrayList<UserPositionItem> parseJSON(InputStream is)
			throws Exception {
		ArrayList<UserPositionItem> list = new ArrayList<UserPositionItem>();
		UserPositionItem item = null;
		// 将字符串转换为jsonarray格式
		String data = StreamTools.streamToString(is);
		JSONArray array = new JSONArray(data);
		int length = array.length();

		for (int i = 0; i < length; i++) {
			JSONObject object = array.getJSONObject(i);
			item = new UserPositionItem(object.getString(IPosition.UserId),
					object.getInt(IPosition.Grid_x),
					object.getInt(IPosition.Grid_y),
					object.getDouble(IPosition.Latitude),
					object.getDouble(IPosition.Longitude));
			list.add(item);
		}

		return list;
	}

}
XuanrenLu 2015-05-28
  • 打赏
  • 举报
回复
引用 2 楼 u013421223 的回复:
访问网络不要放在主线程。
的却是没有放在主线程里面呢
hn_刘潇 2015-05-27
  • 打赏
  • 举报
回复
开线程,或者把service改成IntentService试试
七步777 2015-05-27
  • 打赏
  • 举报
回复
访问网络不要放在主线程。
Hare_ 2015-05-27
  • 打赏
  • 举报
回复
service也是主线程,在service访问网络当然卡住,在service里另启线程来访问网络
yzhang1_00 2015-05-27
  • 打赏
  • 举报
回复
可以放在AsyncTask里实现,但不能在主线程里。
navalphantom 2015-05-27
  • 打赏
  • 举报
回复
连网, File IO等这类型耗时操作,最好是采用线程池来操作。

80,358

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧