我是android开发的新手。
现在我有执行HTTP请求(REST Web服务)的公共类
问题在于我不知道如何使用AsyncTask,因此每当请求过程花费很长时间时,它都会使应用程序无响应并冻结。
这是我的代码
public class RESTClient {
private ArrayList<NameValuePair> params;
private ArrayList <NameValuePair> headers;
private String url;
private int responseCode;
private String message;
private String response;
public String getResponse() {
return response;
}
public String getErrorMessage() {
return message;
}
public int getResponseCode() {
return responseCode;
}
public enum RequestMethod
{
GET,
POST,
PUT,
DELETE
}
public RESTClient(String url)
{
this.url = url;
params = new ArrayList<NameValuePair>();
headers = new ArrayList<NameValuePair>();
}
public void AddParam(String name, String value)
{
params.add(new BasicNameValuePair(name, value));
}
public void AddHeader(String name, String value)
{
headers.add(new BasicNameValuePair(name, value));
}
public void Execute(RequestMethod method) throws Exception
{
switch(method) {
case GET:
{
//add parameters
String combinedParams = "";
if(!params.isEmpty()){
combinedParams += "?";
for(NameValuePair p : params)
{
String paramString = URLEncoder.encode(p.getValue(), "UTF-8");
if(combinedParams.length() > 1)
{
combinedParams += "|" + paramString;
}
else
{
combinedParams += paramString;
}
}
}
HttpGet request = new HttpGet(url);
executeRequest(request, url);
break;
}
case POST:
{
HttpPost request = new HttpPost(url);
//add headers
for(NameValuePair h : headers)
{
request.addHeader(h.getName(), h.getValue());
}
if(!params.isEmpty()){
NameValuePair param = params.get(0);
String val = param.getValue();
StringEntity data = new StringEntity("{\"Value\": \"" + val + "\"}");
data.setContentType("application/json");
request.setEntity(data);
}
executeRequest(request, url);
break;
}
case PUT:
{
HttpPut request = new HttpPut(url);
//add headers
for(NameValuePair h : headers)
{
request.addHeader(h.getName(), h.getValue());
}
if(!params.isEmpty()){
NameValuePair param = params.get(0);
String val = param.getValue();
StringEntity data = new StringEntity("{\"Value\": \"" + val + "\"}");
data.setContentType("application/json");
request.setEntity(data);
}
executeRequest(request, url);
break;
}
case DELETE:
{
HttpDelete request = new HttpDelete(url);
//add parameters
String combinedParams = "";
if(!params.isEmpty()){
combinedParams += "?";
for(NameValuePair p : params)
{
String paramString = URLEncoder.encode(p.getValue(), "UTF-8");
if(combinedParams.length() > 1)
{
combinedParams += "|" + paramString;
}
else
{
combinedParams += paramString;
}
}
}
executeRequest(request, url);
break;
}
}
}
private void executeRequest(HttpUriRequest request, String url)
{
HttpClient client = new DefaultHttpClient();
HttpResponse httpResponse;
try {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
httpResponse = client.execute(request);
responseCode = httpResponse.getStatusLine().getStatusCode();
message = httpResponse.getStatusLine().getReasonPhrase();
HttpEntity entity = httpResponse.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
response = convertStreamToString(instream);
// Closing the input stream will trigger connection release
instream.close();
}
} catch (ClientProtocolException e) {
client.getConnectionManager().shutdown();
e.printStackTrace();
} catch (IOException e) {
client.getConnectionManager().shutdown();
e.printStackTrace();
}
}
private static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
}
有没有办法将asyncTask进程包含到我的类中?
- EDITED - 使用疯狂的sciendtist后
public class RESTClient {
private ArrayList<NameValuePair> params;
private ArrayList <NameValuePair> headers;
private String url;
private int responseCode;
private String message;
ProgressDialog progressBar;
private String response;
private Context mContext;
public String getResponse() {
return response;
}
public String getErrorMessage() {
return message;
}
public int getResponseCode() {
return responseCode;
}
public enum RequestMethod
{
GET,
POST,
PUT,
DELETE
}
public RESTClient(String url)
{
this.url = url;
params = new ArrayList<NameValuePair>();
headers = new ArrayList<NameValuePair>();
}
public void AddParam(String name, String value)
{
params.add(new BasicNameValuePair(name, value));
}
public void AddHeader(String name, String value)
{
headers.add(new BasicNameValuePair(name, value));
}
public String Execute(RequestMethod method) throws Exception
{
switch(method) {
case GET:
{
//add parameters
String combinedParams = "";
if(!params.isEmpty()){
combinedParams += "?";
for(NameValuePair p : params)
{
String paramString = URLEncoder.encode(p.getValue(), "UTF-8");
if(combinedParams.length() > 1)
{
combinedParams += "|" + paramString;
}
else
{
combinedParams += paramString;
}
}
}
HttpGet request = new HttpGet(url);
// IM CALLING THE ASYNCTASK HERE
return new HttpRequest(request, url).get();
break;
}
default:
return "";
break;
}
}
private void executeRequest(HttpUriRequest request, String url)
{
HttpClient client = new DefaultHttpClient();
HttpResponse httpResponse;
try {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
httpResponse = client.execute(request);
responseCode = httpResponse.getStatusLine().getStatusCode();
message = httpResponse.getStatusLine().getReasonPhrase();
HttpEntity entity = httpResponse.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
response = convertStreamToString(instream);
// Closing the input stream will trigger connection release
instream.close();
}
} catch (ClientProtocolException e) {
client.getConnectionManager().shutdown();
e.printStackTrace();
} catch (IOException e) {
client.getConnectionManager().shutdown();
e.printStackTrace();
}
}
private static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}
private class HttpRequest extends AsyncTask<HttpUriRequest,Void, String> {
private HttpUriRequest httpUriRequest;
private String url;
public HttpRequest(HttpUriRequest httpUriRequest , String url) {
this.httpUriRequest = httpUriRequest;
this.url = url;
}
@Override
protected String doInBackground(HttpUriRequest... params) {
// perform all network task on a different thread (i.e not on the main thread)
HttpClient client = new DefaultHttpClient();
String response=null;
HttpResponse httpResponse;
try {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
httpResponse = client.execute(httpUriRequest);
responseCode = httpResponse.getStatusLine().getStatusCode();
message = httpResponse.getStatusLine().getReasonPhrase();
HttpEntity entity = httpResponse.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
response = convertStreamToString(instream);
// Closing the input stream will trigger connection release
instream.close();
}
} catch (ClientProtocolException e) {
client.getConnectionManager().shutdown();
e.printStackTrace();
} catch (IOException e) {
client.getConnectionManager().shutdown();
e.printStackTrace();
}
// return the response;
return response;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
// do not forget to add a progress dialog here or a progressbar
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (!TextUtils.isEmpty(s)){
// on succesfull callback. hide the progres bar or dialog
}
}
}
}
这是我调用异步restclient时的活动,我需要得到json的响应
Login.Java
public class Login extends AppCompatActivity {
private static String URLService;
// UI references.
private EditText USERID;
private EditText PASSWORD;
private View mProgressView;
private View mLoginFormView;
public static String UserID;
private static String Version="3.0";
private String VersionID;
private String VersionStatus;
private String hashed="";
private String Enc_Pass="";
private int responseCode;
Context context;
ProgressDialog mProgressDialog;
private String message;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// Set up the login form.
USERID = (EditText)findViewById(R.id.userID);
//populateAutoComplete();
URLService = getString(R.string.URLService);
Enc_Pass = getString(R.string.password_encryption);
PASSWORD = (EditText) findViewById(R.id.password);
Button LOGINBUTTON = (Button) findViewById(R.id.email_sign_in_button);
LOGINBUTTON.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
attemptLogin();
}
});
mProgressView = findViewById(R.id.login_progress);
SharedPreferences pref = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
UserID = pref.getString("userId", "");
if (!UserID.toString().equals(""))
{
Intent i = new Intent(Login.this, Index.class);
startActivity(i);
}
else
{
}
}
private void attemptLogin() {
// Reset errors.
USERID.setError(null);
PASSWORD.setError(null);
// Store values at the time of the login attempt.
try {
String valueEncrypt = strUserId + "|" + strPassword;
String encc = "";
try {
encc = AndroidCrypt.encrypt(Enc_Pass,valueEncrypt);
encc = encc.replace("+", "%2B");
}catch (GeneralSecurityException e){
//handle error
}
// new BigProccess(Login.this, ProgressDialog.STYLE_SPINNER).execute();
// new HttpRequestMet(URLService+"do?method=dologin&value=" +encc,"GET").execute();
RESTClient client = new RESTClient(URLService+"do?method=dologin&value=" +encc);
client.Execute(RESTClient.RequestMethod.GET);
String response = client.getResponse();
response = response.replace("\\\"", "\"");
response = response.substring(1, response.length() - 1);
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(response);
Status = jsonObject.get("Status").toString();
if (Status == "true") {
String dataku = jsonObject.get("Data").toString();
try {
dataku = AndroidCrypt.decrypt(Enc_Pass, dataku);
}catch (GeneralSecurityException e){
//handle error - could be due to incorrect password or tampered encryptedMsg
}
JSONParser parser = new JSONParser();
JSONObject structure = (JSONObject) parser.parse(dataku);
Toast.makeText(getApplicationContext(), "Welcome Back Mr./Mrs. " + FullName,
Toast.LENGTH_SHORT).show();
Intent i = new Intent(Login.this, Index.class);
startActivity(i);
// finish();
} else {
Toast.makeText(getApplicationContext(), "Login Failed",
Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),"Cant Connect to server, please try again later",
Toast.LENGTH_SHORT).show();
}
}
}
}
答案 0 :(得分:0)
只需将您的网络操作放在AsyncTask中,
class HTTPAsyncTask extends AsyncTask<String, Void, Boolean> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Boolean doInBackground(String... urls) {
HttpGet request = new HttpGet(url);
executeRequest(request, url);
return false;
}
protected void onPostExecute(Boolean result) {
}
在类编写的任何地方执行AsyncTask,
new HTTPAsyncTask().execute("");
答案 1 :(得分:0)
欢迎使用Android Dev,Android(UI线程)中有一个主线程,可以进行所有视图操作。建议不要对这些线程执行繁重的计算或FileSystem操作或NetworkTasks,因为视图依赖于此线程。
作为这个问题的解决方案,android支持Worker threads,它可以处理这些繁重的操作。
AsyncTask
是实现此结构的好方法。 Read the doc here
就您的代码而言,您可以在同一个文件中创建一个新类
private class HttpRequest extends AsyncTask<Void,Void, String>{
private HttpUriRequest httpUriRequest;
private String url;
public HttpRequest(HttpUriRequest httpUriRequest , String url) {
this.httpUriRequest = httpUriRequest;
this.url = url;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
// do not forget to add a progress dialog here or a progressbar
progressBar.show();
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (!TextUtils.isEmpty(s)){
// on succesfull callback. hide the progres bar or dialog
progressBar.gone();
}
}
@Override
protected String doInBackground(Void... voids) {
// perform all network task on a different thread (i.e not on the main thread)
HttpClient client = new DefaultHttpClient();
String response=null;
HttpResponse httpResponse;
try {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
httpResponse = client.execute(request);
responseCode = httpResponse.getStatusLine().getStatusCode();
message = httpResponse.getStatusLine().getReasonPhrase();
HttpEntity entity = httpResponse.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
response = convertStreamToString(instream);
// Closing the input stream will trigger connection release
instream.close();
}
} catch (ClientProtocolException e) {
client.getConnectionManager().shutdown();
e.printStackTrace();
} catch (IOException e) {
client.getConnectionManager().shutdown();
e.printStackTrace();
}
// return the response;
return response;
}
}
您需要做的就是使用自定义Contructor
离。 new HttpRequest(httpUriRequest, url).execute();
并使用onPostExecute()
方法处理了响应。
此外,由于您是一个小推荐,尝试使用第一个字母作为小写命名方法名称,这样您就可以将类与其方法区分开来。
尝试Retrofit比HttpRequests的原生方式更酷,