在我的应用程序中,我想检查设备上的网络状态,如果在设备上没有检测到网络连接,我想显示一个没有网络连接的Toast,然后退出应用程序。如果在设备上检测到连接,那么我必须从webservice加载一个列表并将其显示在屏幕上
我在应用程序的onCreate函数中完成了以下代码。它在模拟器上运行但在真实设备上运行。这在设备上显示ANR的原因是我试图在UI上处理这么多线程,这在android中不受欢迎。请使用AsyncTask指导我如何做到这一点。
任何代码段或指向教程或建议的链接都会对我有所帮助
boolean connected = false;
ConnectivityManager connectivitymanager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkinfo = connectivitymanager.getActiveNetworkInfo();
connected = networkinfo != null && networkinfo.isAvailable()
&& networkinfo.isConnected();
Log.v("Message ", connected + "");
Log.v("Message ", networkinfo.getReason());
//Toast.makeText(CategoryActivity.this, connected + "", 2000).show();
//connected = false;
Log.v("Message 1", connected + "");
if (connected == false) {
CategoryActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
// Log.v("Message ", connected + "");
Toast.makeText(CategoryActivity.this,
"No Internet Connection detected on device", 3000).show();
}
});
Handler handler1 = new Handler();
handler1.postDelayed(new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
finish();
System.exit(0);
}
}), 4000);
} else {
CategoryArray = new JSONArray();
final ProgressDialog pd = ProgressDialog.show(
CategoryActivity.this, "", "Loading...", false, true);
pd.setIcon(getResources().getDrawable(R.drawable.icon));
new Thread() {
public void run() {
try {
sleep(5000);
// Log.v("TAG","in try block");
} catch (Exception e) {
// Log.e("tag", e.getMessage());
}
pd.dismiss();
// Log.v("TAG","progress dismiss");
}
}.start();
handler.postDelayed(new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
CategoryArray = CW
.getCategory("http://www.balajeebazaar.com/RestServiceImpl.svc/categorydetails");
// TODO: handle exception
for (int i = 0; i <= CategoryArray.length() - 1; i++) {
try {
String[] val = new String[3];
Log.v("category array : ",
CategoryArray.getString(i));
val = CategoryArray.getString(i).split(",");
CategoryID.add(i, val[0]);
CategoryList.add(i, val[1]);
val = null;
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
adapter = new CategoryListAdapter(CategoryActivity.this,
CategoryList);
list.setAdapter(adapter);
}
}), 5000);
由于
修改
ERROR/AndroidRuntime(5486): Uncaught handler: thread AsyncTask #1 exiting due to uncaught exception
ERROR/AndroidRuntime(5486): java.lang.RuntimeException: An error occured while executing doInBackground()
ERROR/AndroidRuntime(5486): at android.os.AsyncTask$3.done(AsyncTask.java:200)
ERROR/AndroidRuntime(5486): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:234)
ERROR/AndroidRuntime(5486): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:258)
ERROR/AndroidRuntime(5486): at java.util.concurrent.FutureTask.run(FutureTask.java:122)
ERROR/AndroidRuntime(5486): at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:648)
ERROR/AndroidRuntime(5486): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:673)
ERROR/AndroidRuntime(5486): at java.lang.Thread.run(Thread.java:1060)
ERROR/AndroidRuntime(5486): Caused by: java.lang.ArrayIndexOutOfBoundsException
ERROR/AndroidRuntime(5486): at com.ecommerce.balajeebazaar.CategoryActivity$Loader.doInBackground(CategoryActivity.java:181)
ERROR/AndroidRuntime(5486): at com.ecommerce.balajeebazaar.CategoryActivity$Loader.doInBackground(CategoryActivity.java:1)
ERROR/AndroidRuntime(5486): at android.os.AsyncTask$2.call(AsyncTask.java:185)
11-18 18:30:07.582: ERROR/AndroidRuntime(5486):
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:256)
ERROR/AndroidRuntime(5486): 4 more
答案 0 :(得分:1)
我建议您在应用我在下面发布的解决方案之前先阅读AsyncTask,以便更好地了解正在发生的事情。
这是您Activity
所需要的(它必须替换您发布的所有代码):
boolean connected = false;
ConnectivityManager connectivitymanager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkinfo = connectivitymanager.getActiveNetworkInfo();
connected = networkinfo != null && networkinfo.isAvailable()
&& networkinfo.isConnected();
Log.v("Message ", connected + "");
Log.v("Message ", networkinfo.getReason());
//Toast.makeText(CategoryActivity.this, connected + "", 2000).show();
//connected = false;
Log.v("Message 1", connected + "");
if (connected == false) {
Toast.makeText(CategoryActivity.this, "No Internet Connection detected on device", Toast.LENGTH_LONG ).show();
finish();
} else {
new Loader().execute();
}
这是AsyncTask
,它应该是Activity
的内部类:
private class Loader extends AsyncTask<Void, Void, Void> {
final ProgressDialog pd;
@Override
protected void onPreExecute() {
pd = ProgressDialog.show( CategoryActivity.this, "", "Loading...", false, true);
pd.setIcon(getResources().getDrawable(R.drawable.icon));
super.onPreExecute();
}
@Override
protected Void doInBackground( Void... arg0 ) {
CategoryArray = new JSONArray();
CategoryArray = CW.getCategory("http://www.balajeebazaar.com/RestServiceImpl.svc/categorydetails");
for (int i = 0; i <= CategoryArray.length() - 1; i++) {
try {
String[] val = new String[3];
Log.v("category array : ", CategoryArray.getString(i));
val = CategoryArray.getString(i).split(",");
CategoryID.add(i, val[0]);
CategoryList.add(i, val[1]);
val = null;
} catch (JSONException e) {
e.printStackTrace();
}
}
adapter = new CategoryListAdapter(CategoryActivity.this, CategoryList);
return null;
}
@Override
protected void onPostExecute( Void result ) {
pd.dismiss();
list.setAdapter(adapter);
super.onPostExecute( result );
}
}
注意强>
我无法检查上述内容是否真的有效 - 但它应该让你走上正轨。
答案 1 :(得分:0)
AsyncTasks和Handlers上的一个不错的tutorial。
非常简短,AsyncTask的想法 - 你创建了一个私有类,它在你的Activity中扩展了AsyncTask。 这样做,您可以自动从AsyncTask类访问此活动UI线程。
在AsyncTaks中,您应该注意几种方法。它们被解释为here。
你应该知道的是,只有doInBackground()在一个单独的线程中执行。其他所有内容都在Activity的UI线程上调用,其中定义了AsyncTask。
简单方案:
public class MyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// stuff
new MyAsyncTask().execute(); //this should be invoked only once
}
private class MyAsyncTask() extends AsyncTask<Void, Void, <TypeOfResult Or Void>> {
@Override //executed on the UI thread of MyActivity
protected void onPreExecute() {
super.onPreExecute();
//prepare some stuff
}
@Override //executed in a separate Thread. This thread is automatically handled by AsyncTask
protected <TypeOfResult or Void> doInBackground(Void... params) {
//long operation
}
@Override //executed on the UI thread of MyActivity
protected void onPostExecute(<TypeOf Result Or Void>) {
super.onPostExecute(result);
// do stuff with result from long operation
}
}
}
答案 2 :(得分:0)
您不一定需要AsyncTask,您可以使用常规Java线程来完成您的需要(对于像这样的后台任务来说要容易得多)。