Android 如果我向远程json添加连接(然后解析),为什么此活动会挂起?
我创建了以下活动,如果我向getData方法添加注释,它的负载会很好。若我删除了注释,那个么我将连接到远程url以获取和解析json数据。这似乎会降低活动的负载。 如果我在GetData调用中添加注释,它会立即加载;如果使用GetData,它将在4-5秒内加载。以下是我的活动:Android 如果我向远程json添加连接(然后解析),为什么此活动会挂起?,android,json,http,parsing,connection,Android,Json,Http,Parsing,Connection,我创建了以下活动,如果我向getData方法添加注释,它的负载会很好。若我删除了注释,那个么我将连接到远程url以获取和解析json数据。这似乎会降低活动的负载。 如果我在GetData调用中添加注释,它会立即加载;如果使用GetData,它将在4-5秒内加载。以下是我的活动: public class MyActivity extends Activity implements OnItemSelectedListener { Spinner method; EditText
public class MyActivity extends Activity implements OnItemSelectedListener {
Spinner method;
EditText amount;
EditText address;
EditText email;
EditText total;
Button sendButton;
List<String> methods;
String selected_method;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
method = (Spinner) findViewById(R.id.spinnerBuy); // Spinner element
amount = (EditText) findViewById(R.id.editImporto);
address = (EditText) findViewById(R.id.editAddress);
email = (EditText) findViewById(R.id.editEmail);
total = (EditText) findViewById(R.id.editTotale);
sendButton = (Button) findViewById(R.id.button);
method.setOnItemSelectedListener(this);
methods = new ArrayList<String>();
methods.add("Method 1");
methods.add("Method 2");
methods.add("Method 3");
methods.add("Method 4");
ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, R.layout.my_simple_spinner_item, methods);
dataAdapter.setDropDownViewResource(R.layout.my_simple_spinner_dropdown_item);
method.setAdapter(dataAdapter);
try {
getData();
} catch (JSONException e) {
e.printStackTrace();
}
}
public void getData() throws JSONException {
int timeout = 10;
String jsonString = null;
BasicHttpParams basicParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(basicParams, timeout * 1000);
HttpConnectionParams.setSoTimeout(basicParams, timeout * 1000 );
DefaultHttpClient client = new DefaultHttpClient(basicParams);
HttpGet request = new HttpGet("https://www.example.com/data.json");
request.addHeader("Cache-Control", "no-cache");
try {
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
InputStreamReader in = new InputStreamReader(entity.getContent());
BufferedReader reader = new BufferedReader(in);
StringBuilder stringBuilder = new StringBuilder();
String line = "";
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
jsonString = stringBuilder.toString();
} catch (SocketTimeoutException e) {
e.printStackTrace();
} catch (SocketException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
问题可能是什么以及如何解决?这是因为所有网络操作都必须在非UI线程中完成。您可以使用异步类进行如下网络操作:
private class GetDataAsync extends AsyncTask<Void, Void, Void > {
@Override
protected Void doInBackground(Void... voids) {
//Get Data
getData();
return null;
}
@Override
protected void onPostExecute(void result) {
//anything you want to do it on UI
}
}
您必须使用异步类运行网络操作。Async类有一个方法,您可以重写该方法,该方法称为doInBackground,它不在UI线程上运行
private class MyAsyncTask extends AsyncTask<String, String, String>{
@Override
protected String doInBackground(String... params) {
//Here write your network request
//to obtain result instead of returning null..return the String reply
return reply;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
//This part runs after the async is ready, and yes this is back to the UI thread
//s is the reply from the doInBackgroud returned value
}
}
更新-进度条
要包含进度条,还必须覆盖onPreExecute方法..,该方法也在ui线程中运行,并在doInBackground方法之前运行..因此在preExecute上显示进度条
首先声明一个全局进度条
ProgressDialog progress;
然后是预执行方法
@Override
protected void onPreExecute() {
super.onPreExecute();
progress = ProgressDialog.show(this, "dialog title",
"dialog message", true);
}
并在postExecute中添加
progress.dismiss();
删除进度条的步骤
更新!!-网络连接
您可以使用此方法检查网络
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager
= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
使用
这是因为您正在进行网络操作。因此,这显然需要更长的时间。甚至是你的代码:P。你知道优化它的方法吗?@smartmouse:使用它可以工作,现在它可以立即加载。这是我第一次使用AsyncTask。。。那么现在如何将在AsyncTask中获得的值返回到主活动?我正在更新应答请参见更新的应答..在DoonBackground中以字符串形式返回应答..并将其捕获到postExecute方法抱歉,您能告诉我如何添加进度条吗?因为在值可用之前,我得到一个nullPointerException。。。我的意思是:不,请使用YourActivityName。如果您在片段中,请使用主机活动名称。这是我第一次使用AsyncTask。如何将stringBuilder的值返回到主活动?
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager
= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
if(isNetworkAvailable(context)){
new MyAsyncTask().execute();
}else{
//No Internet don't run task
}