如何使 UI 即使点击加载按钮也能响应
How to make UI responsive even clicking loading button
任何人都可以帮助我如何使列表视图即使单击加载也能响应 button.I 我正在尝试使用下面的代码,但是在加载过程中它崩溃了,如果我尝试单击列表视图应用程序崩溃了。
protected void onPreExecute() {
super.onPreExecute();
new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
imgvw.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
// new Thread();
v.setVisibility(View.INVISIBLE);
View progressBar12 = findViewById(R.id.progressBar12);
progressBar12.setVisibility(View.VISIBLE);
Toast.makeText(getApplicationContext(), "Background Fetch",0).show();
imgvw.refreshDrawableState();
isrefresh = true;
try {
new InqLis();
} catch (Exception e) {
System.out.println("Errors are:"+e);
}
}
});
}
});
Thread.sleep(300);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
manojAdapter.notifyDataSetChanged();
manojAdapter.notifyDataSetInvalidated();
}
}.start();
View progressBar12 = findViewById(R.id.progressBar12);
progressBar12.setVisibility(View.GONE);
imgvw.setVisibility(View.VISIBLE);
}
02-18 21:17:33.382: E/InputEventReceiver(26835): Exception dispatching input event.
02-18 21:17:33.383: E/MessageQueue-JNI(26835): Exception in MessageQueue callback: handleReceiveCallback
02-18 21:17:33.436: E/MessageQueue-JNI(26835): java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(16908298, class com.handmark.pulltorefresh.library.PullToRefreshExpandableListView$InternalExpandableListViewSDK9) with Adapter(class android.widget.ExpandableListConnector)]
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.widget.ListView.layoutChildren(ListView.java:1555)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.widget.AbsListView.onTouchUp(AbsListView.java:3617)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.widget.AbsListView.onTouchEvent(AbsListView.java:3429)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.View.dispatchTouchEvent(View.java:7736)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2212)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1945)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2068)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1515)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.app.Activity.dispatchTouchEvent(Activity.java:2466)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2016)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.View.dispatchPointerEvent(View.java:7916)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4030)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3909)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3459)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3509)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3478)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3585)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3486)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3642)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3459)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3509)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3478)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3486)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3459)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5727)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:56
首先,您似乎正在使用 asyncTask。
我会查看 android 开发人员文档以正确使用:AsyncTask
一个asyctask有3个主要部分:
- onPreExecute- 在 UI 线程上运行
- doInBackground- 在后台线程上运行
- onPostExecute- 在 UI 线程上运行
所以:
在 onPreExecute 中显示加载对话框
在 doInBackground 做你的主要工作
在 onPostExecute 中隐藏加载对话框并用结果
更新你的 UI
此过程将为您提供响应迅速且线程安全的解决方案。(并且您不必使用可运行或睡眠线程)
其次:
你的错误是:
The content of the adapter has changed but ListView did not receive a notification.
这很可能是由于线程休眠时间过长造成的。这会导致在未调用 notifyDataSetChanged()
的情况下更改适配器的内容。
结论:最可靠的解决方案是使用 AsyncTask 的 doInBackground 方法进行后台工作。
下面是一个正确使用 AsyncTask 的例子:
private static class ExampleAsync extends AsyncTask<Void, Void, ArrayList<ExampleObject>> {
private GenericRecycler adapter;
public ExampleAsync(GenericRecycler theAdapter){
this.adapter = theAdapter;
}
@Override //runs on main UI Thread
protected void onPreExecute() {
super.onPreExecute();
//make any UI changes here to display while loading
}
// runs in a seperate thread
@Override
protected ArrayList<ExampleObject> doInBackground(Void... params) {
ArrayList<ExampleObject> exampleList = new ArrayList<ExampleObject>(10);
//waiting instead of doing work
//this is where you should do an http request and create a list of data
synchronized (this){
try {
wait(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return exampleList;
}
//this runs on main ui thread
@Override
protected void onPostExecute(ArrayList<ExampleObject> objects){
adapter.setData(objects);
//any time that data in adapter is changed, notifydatasetchanged() must be called
adapter.notifyDataSetChanged();
}
}
任何人都可以帮助我如何使列表视图即使单击加载也能响应 button.I 我正在尝试使用下面的代码,但是在加载过程中它崩溃了,如果我尝试单击列表视图应用程序崩溃了。
protected void onPreExecute() {
super.onPreExecute();
new Thread() {
public void run() {
while (i++ < 1000) {
try {
runOnUiThread(new Runnable() {
@Override
public void run() {
imgvw.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
// new Thread();
v.setVisibility(View.INVISIBLE);
View progressBar12 = findViewById(R.id.progressBar12);
progressBar12.setVisibility(View.VISIBLE);
Toast.makeText(getApplicationContext(), "Background Fetch",0).show();
imgvw.refreshDrawableState();
isrefresh = true;
try {
new InqLis();
} catch (Exception e) {
System.out.println("Errors are:"+e);
}
}
});
}
});
Thread.sleep(300);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
manojAdapter.notifyDataSetChanged();
manojAdapter.notifyDataSetInvalidated();
}
}.start();
View progressBar12 = findViewById(R.id.progressBar12);
progressBar12.setVisibility(View.GONE);
imgvw.setVisibility(View.VISIBLE);
}
02-18 21:17:33.382: E/InputEventReceiver(26835): Exception dispatching input event.
02-18 21:17:33.383: E/MessageQueue-JNI(26835): Exception in MessageQueue callback: handleReceiveCallback
02-18 21:17:33.436: E/MessageQueue-JNI(26835): java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. Make sure your adapter calls notifyDataSetChanged() when its content changes. [in ListView(16908298, class com.handmark.pulltorefresh.library.PullToRefreshExpandableListView$InternalExpandableListViewSDK9) with Adapter(class android.widget.ExpandableListConnector)]
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.widget.ListView.layoutChildren(ListView.java:1555)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.widget.AbsListView.onTouchUp(AbsListView.java:3617)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.widget.AbsListView.onTouchEvent(AbsListView.java:3429)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.View.dispatchTouchEvent(View.java:7736)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2212)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1945)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2218)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:1959)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:2068)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1515)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.app.Activity.dispatchTouchEvent(Activity.java:2466)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:2016)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.View.dispatchPointerEvent(View.java:7916)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4030)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:3909)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3459)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3509)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3478)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:3585)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3486)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:3642)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3459)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:3509)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:3478)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:3486)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:3459)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5727)
02-18 21:17:33.436: E/MessageQueue-JNI(26835): at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:56
首先,您似乎正在使用 asyncTask。
我会查看 android 开发人员文档以正确使用:AsyncTask
一个asyctask有3个主要部分:
- onPreExecute- 在 UI 线程上运行
- doInBackground- 在后台线程上运行
- onPostExecute- 在 UI 线程上运行
所以: 在 onPreExecute 中显示加载对话框 在 doInBackground 做你的主要工作 在 onPostExecute 中隐藏加载对话框并用结果
更新你的 UI此过程将为您提供响应迅速且线程安全的解决方案。(并且您不必使用可运行或睡眠线程)
其次:
你的错误是:
The content of the adapter has changed but ListView did not receive a notification.
这很可能是由于线程休眠时间过长造成的。这会导致在未调用 notifyDataSetChanged()
的情况下更改适配器的内容。
结论:最可靠的解决方案是使用 AsyncTask 的 doInBackground 方法进行后台工作。
下面是一个正确使用 AsyncTask 的例子:
private static class ExampleAsync extends AsyncTask<Void, Void, ArrayList<ExampleObject>> {
private GenericRecycler adapter;
public ExampleAsync(GenericRecycler theAdapter){
this.adapter = theAdapter;
}
@Override //runs on main UI Thread
protected void onPreExecute() {
super.onPreExecute();
//make any UI changes here to display while loading
}
// runs in a seperate thread
@Override
protected ArrayList<ExampleObject> doInBackground(Void... params) {
ArrayList<ExampleObject> exampleList = new ArrayList<ExampleObject>(10);
//waiting instead of doing work
//this is where you should do an http request and create a list of data
synchronized (this){
try {
wait(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return exampleList;
}
//this runs on main ui thread
@Override
protected void onPostExecute(ArrayList<ExampleObject> objects){
adapter.setData(objects);
//any time that data in adapter is changed, notifydatasetchanged() must be called
adapter.notifyDataSetChanged();
}
}