如果我将连接添加到远程 json(然后解析),为什么这个 activity 会挂起?
Why this activity hangs if i add connection to remote json (and then parsing)?
我创建了以下 activity,如果我向 getData() 方法添加注释,它会加载得很好。如果我删除评论然后我连接到远程 url 来获取和解析 json 数据。这似乎使 activity 的负载变慢。
如果我向 GetData() 调用添加注释,它会立即加载;如果使用 GetData(),它会在 4-5 秒内加载。这是我的 activity:
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
}
}
您必须 运行 使用异步 class 进行网络操作。 Async class 有一个方法,您可以重写名为 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
}
}
那你运行任务就这样
new MyAsyncTask().execute();
更新 - 进度条
要包含进度条,您还必须覆盖 onPreExecute 方法..它也在 ui 线程中 运行s 并且在 doInBackground 方法之前 运行s..所以在 preExecute 上显示进度条..
首先声明一个全局进度条
ProgressDialog progress;
然后是预执行方法
@Override
protected void onPreExecute() {
super.onPreExecute();
progress = ProgressDialog.show(this, "dialog title",
"dialog message", true);
}
并在执行后添加
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();
}
使用
if(isNetworkAvailable(context)){
new MyAsyncTask().execute();
}else{
//No Internet don't run task
}
我创建了以下 activity,如果我向 getData() 方法添加注释,它会加载得很好。如果我删除评论然后我连接到远程 url 来获取和解析 json 数据。这似乎使 activity 的负载变慢。 如果我向 GetData() 调用添加注释,它会立即加载;如果使用 GetData(),它会在 4-5 秒内加载。这是我的 activity:
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
}
}
您必须 运行 使用异步 class 进行网络操作。 Async class 有一个方法,您可以重写名为 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
}
}
那你运行任务就这样
new MyAsyncTask().execute();
更新 - 进度条
要包含进度条,您还必须覆盖 onPreExecute 方法..它也在 ui 线程中 运行s 并且在 doInBackground 方法之前 运行s..所以在 preExecute 上显示进度条..
首先声明一个全局进度条
ProgressDialog progress;
然后是预执行方法
@Override
protected void onPreExecute() {
super.onPreExecute();
progress = ProgressDialog.show(this, "dialog title",
"dialog message", true);
}
并在执行后添加
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();
}
使用
if(isNetworkAvailable(context)){
new MyAsyncTask().execute();
}else{
//No Internet don't run task
}