android怎么刷新适配器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android怎么刷新适配器相关的知识,希望对你有一定的参考价值。
参考技术A totalList = list; adapter.notifyDataSetChanged(); totalList.addAll(list); adapter.notifyDataSetChanged(); //这就是刷新适配器的方法 参考技术B 用对象点这个notifyDataSetChanged(); 方法就可以刷新适配器了Adapter.notifyDataSetChanged();
就像这样,帮助到你请采纳。。。。
尝试刷新内容时,Android JsonReader 已关闭
【中文标题】尝试刷新内容时,Android JsonReader 已关闭【英文标题】:Android JsonReader is closed when attempting to refresh content 【发布时间】:2017-01-02 19:23:37 【问题描述】:目前,我正在开发一个在列表视图中显示基于 JSON 的 API 内容的应用程序。第一次获取数据并使用适配器填充列表视图可以正常工作。但是当我尝试使用 Swipe 刷新内容时,第一次尝试刷新时出现 IllegalStateException 错误:
W/System.err: java.lang.IllegalStateException: JsonReader is closed
W/System.err: at android.util.JsonReader.peek(JsonReader.java:361)
W/System.err: at android.util.JsonReader.expect(JsonReader.java:308)
W/System.err: at android.util.JsonReader.beginArray(JsonReader.java:277)
W/System.err: at com.cologne_international.cologneinternationalapp.notamActivity.readNotamArray(notamActivity.java:71)
W/System.err: at com.cologne_international.cologneinternationalapp.notamActivity.readJsonStream(notamActivity.java:63)
W/System.err: at com.cologne_international.cologneinternationalapp.notamActivity.updateNOTAMS(notamActivity.java:122)
W/System.err: at com.cologne_international.cologneinternationalapp.notamActivity$1.onRefresh(notamActivity.java:48)
W/System.err: at android.support.v4.widget.SwipeRefreshLayout$1.onAnimationEnd(SwipeRefreshLayout.java:187)
W/System.err: at android.support.v4.widget.CircleImageView.onAnimationEnd(CircleImageView.java:106)
W/System.err: at android.view.ViewGroup.finishAnimatingView(ViewGroup.java:6237)
W/System.err: at android.view.View.draw(View.java:17129)
W/System.err: at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
W/System.err: at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
W/System.err: at android.view.View.draw(View.java:17188)
W/System.err: at android.view.View.updateDisplayListIfDirty(View.java:16167)
W/System.err: at android.view.View.draw(View.java:16951)
W/System.err: at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
W/System.err: at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
W/System.err: at android.view.View.updateDisplayListIfDirty(View.java:16162)
W/System.err: at android.view.View.draw(View.java:16951)
W/System.err: at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
W/System.err: at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
W/System.err: at android.view.View.updateDisplayListIfDirty(View.java:16162)
W/System.err: at android.view.View.draw(View.java:16951)
W/System.err: at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
W/System.err: at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
W/System.err: at android.view.View.updateDisplayListIfDirty(View.java:16162)
W/System.err: at android.view.View.draw(View.java:16951)
W/System.err: at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
W/System.err: at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
W/System.err: at android.view.View.updateDisplayListIfDirty(View.java:16162)
W/System.err: at android.view.View.draw(View.java:16951)
W/System.err: at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
W/System.err: at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
W/System.err: at android.view.View.updateDisplayListIfDirty(View.java:16162)
W/System.err: at android.view.View.draw(View.java:16951)
W/System.err: at android.view.ViewGroup.drawChild(ViewGroup.java:3727)
W/System.err: at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3513)
W/System.err: at android.view.View.draw(View.java:17188)
W/System.err: at com.android.internal.policy.DecorView.draw(DecorView.java:753)
W/System.err: at android.view.View.updateDisplayListIfDirty(View.java:16167)
W/System.err: at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:648)
W/System.err: at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:654)
W/System.err: at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:762)
W/System.err: at android.view.ViewRootImpl.draw(ViewRootImpl.java:2800)
W/System.err: at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2608)
W/System.err: at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2215)
W/System.err: at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
W/System.err: at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6337)
W/System.err: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
W/System.err: at android.view.Choreographer.doCallbacks(Choreographer.java:686)
W/System.err: at android.view.Choreographer.doFrame(Choreographer.java:621)
W/System.err: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
W/System.err: at android.os.Handler.handleCallback(Handler.java:751)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
W/System.err: at android.os.Looper.loop(Looper.java:154)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6119)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
但是,当我再次尝试重新加载时,一切正常。 notamActivity 类:
public class notamActivity extends AppCompatActivity
private static ListView lv;
private static AdapterNotam adbNotam;
private static SwipeRefreshLayout swipeContainer;
private static JsonReader reader;
private static Context context;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notam);
context = getApplicationContext();
lv = (ListView) findViewById(R.id.list);
try
adbNotam = new AdapterNotam(this, readJsonStream());
catch (Exception e)
e.printStackTrace();
lv.setAdapter(adbNotam);
swipeContainer = (SwipeRefreshLayout) findViewById(R.id.swiperefresh);
swipeContainer.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener()
@Override
public void onRefresh()
Log.i("Called onRefresh", "onRefresh called from SwipeRefreshLayout");
notamActivity.updateNOTAMS();
);
public static List<Notam> readJsonStream() throws IOException
try
return readNotamArray(reader);
finally
reader.close();
public static List<Notam> readNotamArray(JsonReader reader) throws IOException
List<Notam> notams = new ArrayList<Notam>();
reader.beginArray();
while (reader.hasNext())
notams.add(readNotam(reader));
reader.endArray();
return notams;
public static Notam readNotam(JsonReader reader) throws IOException
int id = 0;
String datestart = null;
String dateend = null;
String text = null;
reader.beginObject();
while (reader.hasNext())
String jname = reader.nextName();
if (jname.equals("id"))
id = Integer.parseInt(reader.nextString());
else if (jname.equals("datestart"))
datestart = reader.nextString();
else if (jname.equals("dateend"))
dateend = reader.nextString();
else if (jname.equals("textde"))
text = reader.nextString();
else
reader.skipValue();
reader.endObject();
return new Notam(id, text, datestart, dateend);
public static void setReader(JsonReader pReader)
reader = pReader;
public static Context getContext()
return context;
public static void updateNOTAMS()
new downloadNOTAMTask().execute("http://cologne-international.com/notam/json.php");
try
adbNotam = new AdapterNotam(getContext(), readJsonStream());
catch (Exception e)
e.printStackTrace();
lv.setAdapter(adbNotam);
swipeContainer.setRefreshing(false);
下载NOTAMTask 类:
class downloadNOTAMTask extends AsyncTask<String,Void,JsonReader>
protected JsonReader doInBackground(String... url)
JsonReader reader = null;
try
InputStream ls = new URL(url[0]).openStream();
reader = new JsonReader(new InputStreamReader(ls, "UTF-8"));
catch(Exception e)
e.printStackTrace();
return reader;
protected void onPostExecute(JsonReader result)
notamActivity.setReader(result);
布局xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_event"
android:layout_
android:layout_
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.cologne_international.cologneinternationalapp.eventActivity">
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swiperefresh"
android:layout_
android:layout_
android:layout_above="@+id/bt_back">
<ListView
android:id="@+id/list"
android:layout_
android:layout_
/>
</android.support.v4.widget.SwipeRefreshLayout>
<Button
android:text="@string/button_back"
android:layout_
android:layout_
android:layout_alignParentBottom="true"
android:id="@+id/bt_back"
android:layout_alignParentEnd="true"
android:layout_alignParentStart="true"
android:onClick="back"
style="@android:style/Widget.Holo.Button" />
</RelativeLayout>
【问题讨论】:
你做错了。首先,请不要对您正在处理的所有对象进行静态引用,这可能会导致大量内存泄漏,其次,如果您正在执行 asncTask,您应该等待结果然后进行处理。 【参考方案1】:您在问题中发布的活动存在问题:-
您不应持有对上下文或任何视图的静态引用,这可能会导致内存泄漏 当您使用 AsynTask 时,请尝试传递一个接口以恢复通信,就像我在以下活动中所做的那样。 在后台执行 JSON 解析,因为它可能会以繁重的处理结束并显示 ANR。但是,当我再次尝试重新加载时,一切正常。
这是因为您没有以同步方式做事。 (即,您不是在等待 AsynTask 完成)
下面我为您提供了编写更清晰、更不易出错的代码的参考:-
notamActivity 类:
public class notamActivity extends AppCompatActivity
private ListView lv;
private AdapterNotam adbNotam;
private SwipeRefreshLayout swipeContainer;
private Context context;
private DownloadNOTAMTask downloadNOTAMTask;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notam);
context = getApplicationContext();
lv = (ListView) findViewById(R.id.list);
//to initially get the list of Notams
updateNOTAMS();
swipeContainer = (SwipeRefreshLayout) findViewById(R.id.swiperefresh);
swipeContainer.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener()
@Override
public void onRefresh()
Log.i("Called onRefresh", "onRefresh called from SwipeRefreshLayout");
updateNOTAMS();
);
public void cancelTask(DownloadNOTAMTask downloadNOTAMTask)
if (downloadNOTAMTask != null && downloadNOTAMTask.getStatus() == AsyncTask.Status.RUNNING)
downloadNOTAMTask.cancel(true);
//you should create a reference to cancel the task when the activity is closing
public void updateNOTAMS()
cancelTask(downloadNOTAMTask);
downloadNOTAMTask = new DownloadNOTAMTask(new GenericCallBack()
@Override
public void success(List<Notam> notamList)
//you don't need to setup adapter again and again
//just use setDataSetChanged
adbNotam = new AdapterNotam(notamActivity.this, notamList);
lv.setAdapter(adbNotam);
swipeContainer.setRefreshing(false);
@Override
public void failure()
swipeContainer.setRefreshing(false);
).execute("http://cologne-international.com/notam/json.php");
//interface help you to get callback from the downloadNOTAMTask
interface GenericCallBack
void success(List<Notam> notamList);
void failure();
下载NOTAMTask 类:
public class DownloadNOTAMTask extends AsyncTask<String, Void, List<Notam>>
private final notamActivity.GenericCallBack callBack;
public DownloadNOTAMTask(notamActivity.GenericCallBack genericInterface)
this.callBack = genericInterface;
protected List<Notam> doInBackground(String... url)
JsonReader reader = null;
List<Notam> notamList = null;
try
InputStream ls = new URL(url[0]).openStream();
reader = new JsonReader(new InputStreamReader(ls, "UTF-8"));
notamList = readNotamArray(reader);
reader.close();
catch (IOException e)
e.printStackTrace();
return notamList;
@Override
protected void onPostExecute(List<Notam> notams)
if (callBack != null)
if (notams != null)
callBack.success(notams);
else
callBack.failure();
private List<Notam> readNotamArray(JsonReader reader) throws IOException
List<Notam> notams = new ArrayList<>();
reader.beginArray();
while (reader.hasNext())
notams.add(readNotam(reader));
reader.endArray();
return notams;
private Notam readNotam(JsonReader reader) throws IOException
int id = 0;
String datestart = null;
String dateend = null;
String text = null;
reader.beginObject();
while (reader.hasNext())
String jname = reader.nextName();
switch (jname)
case "id":
id = Integer.parseInt(reader.nextString());
break;
case "datestart":
datestart = reader.nextString();
break;
case "dateend":
dateend = reader.nextString();
break;
case "textde":
text = reader.nextString();
break;
default:
reader.skipValue();
break;
reader.endObject();
return new Notam(id, text, datestart, dateend);
布局xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_event"
android:layout_
android:layout_
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.cologne_international.cologneinternationalapp.eventActivity">
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/swiperefresh"
android:layout_
android:layout_
android:layout_above="@+id/bt_back">
<ListView
android:id="@+id/list"
android:layout_
android:layout_
/>
</android.support.v4.widget.SwipeRefreshLayout>
<Button
android:text="@string/button_back"
android:layout_
android:layout_
android:layout_alignParentBottom="true"
android:id="@+id/bt_back"
android:layout_alignParentEnd="true"
android:layout_alignParentStart="true"
android:onClick="back"
style="@android:style/Widget.Holo.Button" />
</RelativeLayout>
【讨论】:
以上是关于android怎么刷新适配器的主要内容,如果未能解决你的问题,请参考以下文章
Android Q 基站刷新接口源码分析 & 适配双卡手机基站刷新逻辑
Android Q 基站刷新接口源码分析 & 适配双卡手机基站刷新逻辑
Android Q 基站刷新接口源码分析 & 适配双卡手机基站刷新逻辑
Android Q 基站刷新接口源码分析 & 适配双卡手机基站刷新逻辑