现在的位置: 首页 > 综合 > 正文

Configuring a thread-safe HttpClient(MyMoviesWithHttpClient)

2017年12月24日 ⁄ 综合 ⁄ 共 4791字 ⁄ 字号 评论关闭

If you plan to develop applications that only target Android 2.2 or newer, you may consider skipping this technique.

You’re running threads that need to communicate with a web server through a single shared instance of HttpClient, and you must therefore make sure that connections are established in a mutually exclusive, thread-safe manner.

ThreadSafeClientConnManager. This connection manager doesn’t handle a single connection, but a pool of them, where each connection can be taken from the pool, allocated to a thread (which then has exclusive access to it), and returned to the pool once the
thread yields it. If the same or another thread claims a connection for the same route, then a connection can be immediately reused from the pool without the need to first close and reopen it, thereby avoiding the overhead of the handshake performed by HTTP
when establishing a new connection.

Connection pooling isn’t based on thread identity (the same thread getting the same connection back every time), but on routes.

This means that a connection for a request can only be reused from the pool when the request goes to the same target host via the same intermediate hosts using the same layering or tunneling parameters.

One caveat with setting a connection manager manually is that you need to supply a set of HTTP configuration parameters and a protocol scheme registry, even if you
don’t want these things to be different from what DefaultHttpClient uses by default with its SingleClientConnManager.

XML, as a means of configuration, can only be used for resources such as views and the application manifest. Anything else you’ll have to write out in Java code, including your HTTP configuration.

You can use a stati:c initializer to set-up a thread-safe HttpClient instance

public class MyMovies extends ListActivity implements Callback {
	//create static ref to client
	private static final AbstractHttpClient httpClient;
	private static final HttpRequestRetryHandler retryHandler;
	
	private MovieAdapter adapter;
	//static initializer creates object
	static{
		//register dedfault scheme
		SchemeRegistry schemeRegistry=new SchemeRegistry();
		schemeRegistry.register(new Scheme("http",PlainSocketFactory.getSocketFactory(),80));
		HttpParams connMangerParams=new BasicHttpParams();
		ConnManagerParams.setMaxTotalConnections(connMangerParams, 5);
		ConnManagerParams.setMaxConnectionsPerRoute(connMangerParams, new ConnPerRouteBean(5));
		ConnManagerParams.setTimeout(connMangerParams, 15*1000);
		//create thread safe manager
		ThreadSafeClientConnManager cm=new ThreadSafeClientConnManager(connMangerParams,schemeRegistry);
		HttpParams clientParams=new BasicHttpParams();
		HttpProtocolParams.setUserAgent(clientParams, "MyMovies/1.0");
		HttpConnectionParams.setConnectionTimeout(clientParams, 15*1000);
		HttpConnectionParams.setSoTimeout(clientParams, 15 * 1000);
		//create cutomized default HttpClient
		httpClient=new DefaultHttpClient(cm,clientParams);
		retryHandler=new DefaultHttpRequestRetryHandler(5,false){
			public boolean retryRequest(IOException exception,int executionCount,HttpContext context){
				if(!super.retryRequest(exception, executionCount, context)){
					Log.d("HTTP retry-handler", "Won't retry");
					return false;
				}
				try{
					Thread.sleep(2000);
				}catch(InterruptedException e){
					
				}
				Log.d("HTTP retry-handler", "Retrying request...");
				return true;
			}
		};
	}
	
	public static HttpClient getHttpClient(){
		return httpClient;
	}
	
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		
		ListView listView=getListView();
		
		Button backToTop=(Button)getLayoutInflater().inflate(R.layout.list_footer, null);
		backToTop.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(android.R.drawable.ic_menu_upload),
				null, null, null);
		listView.addFooterView(backToTop);
		
		this.adapter=new MovieAdapter(this);
		listView.setAdapter(adapter);
		listView.setItemsCanFocus(false);
		
		new UpdateNoticeTask(new Handler(this)).execute();//starts new download task
	}
	
    public void backToTop(View view) {
        getListView().setSelection(0);
    }
    
    protected void onListItemClick(ListView l, View v, int position, long id) {
    	this.adapter.toggleMovie(position);
    	this.adapter.notifyDataSetInvalidated();
    }
    
	@Override
	public boolean handleMessage(Message msg) {
		// TODO Auto-generated method stub
		String updateNotice=msg.getData().getString("text");//reads update text
		AlertDialog.Builder dialog=new AlertDialog.Builder(this);
		dialog.setTitle("What's new");
		dialog.setMessage(updateNotice);//set update text
		dialog.setIcon(android.R.drawable.ic_dialog_info);
		dialog.setPositiveButton(getString(android.R.string.ok), new OnClickListener(){
			@Override
			public void onClick(DialogInterface dialog, int which) {
				// TODO Auto-generated method stub
				dialog.dismiss();
			}
		});
		dialog.show();
		return false;
	}
	
	
}

if you’re targeting Android 2.2 or above, you don’t have to do anything shown in this technique yourself! As we mentioned briefly before, Android bundles a custom implementation of HttpClient called AndroidHttpClient with that version. This
implementation has already been optimized for mobile use, and it does all the stuff like
setting proper timeouts and a thread-safe connection manager. It also supports HTTPS by default. In order to use it, you’d replace the code at F in listing 9.4 with this:
httpClient = AndroidHttpClient.newInstance("MyMovies/1.0");

抱歉!评论已关闭.