将 ArrayList 的内容放入 ArrayAdapter
Put the contents of ArrayList in ArrayAdapter
我有一个存储 JSON 内容的 ArrayList 和一个显示它的 ArrayAdapter
。现在我正在尝试保存此 JSON 内容,以便用户即使在离线时也能看到它。
我按照这个 SO 问题来这样做:
上面的问题让我们将 ArrayList 保存在外部存储的文件中
现在我想在用户离线时启动应用程序时显示这个存储的 ArrayList 的内容,即 actorList 在我的 arrayAdapter 中。
到目前为止,这是我的代码,当 运行 离线且 NullPointerException
时应用程序崩溃
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_photos, container, false);
if (isNetworkAvailable()) {
actorsList = new ArrayList<Actors>();
new JSONAsyncTask().execute(baseURL);
listview = (ListView) rootView.findViewById(R.id.list);
adapter = new ActorAdapter(getActivity(), R.layout.row, actorsList);
listview.setAdapter(adapter);
}
else{
Toast.makeText(getActivity(), "Network Unavailable. Please Try Again Later ", Toast.LENGTH_LONG).show();
try {
Toast.makeText(getActivity(), "Reached TRY ", Toast.LENGTH_LONG).show();
actorsList = (ArrayList<Actors>)objectFromFile(dataPath);
// System.out.print(actorsList);
for(int i=0;i<actorsList.size();i++)
{
Toast.makeText(getActivity(), "Reached FOR ", Toast.LENGTH_LONG).show();
actor.setName(actorsList.get(i).getName());
actor.setDescription(actorsList.get(i).getDescription());
actor.setImage(actorsList.get(i).getImage());
}
listview = (ListView) rootView.findViewById(R.id.list);
adapter = new ActorAdapter(getActivity(), R.layout.row, actorsList);
listview.setAdapter(adapter);
} catch (Exception e) {
e.printStackTrace();
}
}
return rootView;
}
class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {
@Override
protected void onPreExecute() {
}
@Override
protected Boolean doInBackground(String... urls) {
try {
//------------------>>
HttpGet httppost = new HttpGet(urls[0]);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httppost);
// StatusLine stat = response.getStatusLine();
int status = response.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);
JSONObject jsono = new JSONObject(data);
jarray = jsono.getJSONArray("posts");
for (int i = 0; i < jarray.length(); i++) {
JSONObject object = jarray.getJSONObject(i);
Actors actor = new Actors();
actor.setName(object.getString("title"));
actor.setDescription(object.getString("url"));
actor.setImage(object.getString("thumbnail"));
actorsList.add(actor);
}
return true;
}
} catch (ParseException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean result) {
dialog.cancel();
adapter.notifyDataSetChanged();
if (result) {
try {
dataPath = objectToFile(actorsList);
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(getActivity().getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();
}
}
}
如您所见,我正在尝试实现与上面链接的问题中所问的相同的事情,但无法弄清楚如何在离线时显示 ArrayList
。请帮忙
更新: logcat
04-21 14:23:33.161 4870-4870/info.androidhive.slidingmenu E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: info.androidhive.slidingmenu, PID: 4870
java.lang.RuntimeException: Unable to start activity ComponentInfo{info.androidhive.slidingmenu/info.androidhive.slidingmenu.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2412)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2470)
at android.app.ActivityThread.access0(ActivityThread.java:174)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1307)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5593)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at java.io.File.fixSlashes(File.java:185)
at java.io.File.<init>(File.java:134)
at info.androidhive.slidingmenu.ObjectToFileUtil.objectFromFile(ObjectToFileUtil.java:31)
at info.androidhive.slidingmenu.PagesFragment.onCreateView(PagesFragment.java:176)
at android.app.Fragment.performCreateView(Fragment.java:1700)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
at android.app.BackStackRecord.run(BackStackRecord.java:684)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1453)
at android.app.Activity.performStart(Activity.java:5467)
at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2385)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2470)
at android.app.ActivityThread.access0(ActivityThread.java:174)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1307)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5593)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
这是将 ObjectToFile 和 ObjectFromFile 转换的 Class
package info.androidhive.slidingmenu;
import android.os.Environment;
import java.io.*;
public class ObjectToFileUtil {
public static String objectToFile(Object object) throws IOException {
String path = Environment.getExternalStorageDirectory() + File.separator + "cache" + File.separator;
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
path += "data";
File data = new File(path);
if (!data.createNewFile()) {
data.delete();
data.createNewFile();
}
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(data));
objectOutputStream.writeObject(object);
objectOutputStream.close();
return path;
}
public static Object objectFromFile(String path) throws IOException, ClassNotFoundException {
Object object = null;
File data = new File(path);
if(data.exists()) {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(data));
object = objectInputStream.readObject();
objectInputStream.close();
}
return object;
}
}
更新代码的更新答案
根据这个更改您的 ObjectToFileUtil class-
public class ObjectToFileUtil {
private static baseFilePath = Environment.getExternalStorageDirectory() + File.separator + "cache" + File.separator+"data";
public static String objectToFile(Object object) throws IOException {
String path = baseFilePath;
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
File data = new File(path);
if (!data.createNewFile()) {
data.delete();
data.createNewFile();
}
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(data));
objectOutputStream.writeObject(object);
objectOutputStream.close();
return path;
}
public static Object objectFromFile() throws IOException, ClassNotFoundException {
String path = baseFilePath;
Object object = null;
File data = new File(path);
if(data.exists()) {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(data));
object = objectInputStream.readObject();
objectInputStream.close();
}
return object;
}
然后更改以下行 -
actorsList = (ArrayList<Actors>)objectFromFile(dataPath);
到-
actorsList = (ArrayList<Actors>)objectFromFile();
问题的原因
您在网络可用时保存了文件,并将文件路径存储在 dataPath
成员中。现在,当您在没有网络可用的情况下启动应用程序时,您正在尝试打开文件,假设该文件已经具有 json。到目前为止一切都很好。但是有一个逻辑错误。当您重新启动您的应用程序时,请查看 dataPath
中没有值,尽管文件可能存在,因为 dataPath
仅在您刚刚写入文件时分配。所以你的路径是 null
并且文件对象没有在 objectFromFile()
中创建
还要确保您的 Actors
class 正在实现 Serializable
接口。导致在文件中保存一个对象然后正确地检索它,该对象需要 Serializable
.
您可以将对象数组列表转换为字符串并将其存储在 sharedprefrences 中,如下所示:-
Gson gson = new Gson();
SharedPreferences sharedPreferences= PreferenceManager.getDefaultSharedPreferences(getActivity());
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("list",gson.toJson(actorsList));
editor.commit();
然后你可以在连接不可用的 else 块中检索此列表,如下所示:-
SharedPreferences sharedPreferences= PreferenceManager.getDefaultSharedPreferences(getActivity());
String string=sharedPreferences.sharedPreferences.getString("list",null);
List<Actors> list=new List<Actors>();
Type listType = new TypeToken<ArrayList<Actors>>() {
}.getType();
list= new Gson().fromJson(string, listType);
我在这里使用 gson 来序列化和反序列化对象,并且不要忘记在您的 gradle 文件中包含 gson
我有一个存储 JSON 内容的 ArrayList 和一个显示它的 ArrayAdapter
。现在我正在尝试保存此 JSON 内容,以便用户即使在离线时也能看到它。
我按照这个 SO 问题来这样做:
到目前为止,这是我的代码,当 运行 离线且 NullPointerException
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_photos, container, false);
if (isNetworkAvailable()) {
actorsList = new ArrayList<Actors>();
new JSONAsyncTask().execute(baseURL);
listview = (ListView) rootView.findViewById(R.id.list);
adapter = new ActorAdapter(getActivity(), R.layout.row, actorsList);
listview.setAdapter(adapter);
}
else{
Toast.makeText(getActivity(), "Network Unavailable. Please Try Again Later ", Toast.LENGTH_LONG).show();
try {
Toast.makeText(getActivity(), "Reached TRY ", Toast.LENGTH_LONG).show();
actorsList = (ArrayList<Actors>)objectFromFile(dataPath);
// System.out.print(actorsList);
for(int i=0;i<actorsList.size();i++)
{
Toast.makeText(getActivity(), "Reached FOR ", Toast.LENGTH_LONG).show();
actor.setName(actorsList.get(i).getName());
actor.setDescription(actorsList.get(i).getDescription());
actor.setImage(actorsList.get(i).getImage());
}
listview = (ListView) rootView.findViewById(R.id.list);
adapter = new ActorAdapter(getActivity(), R.layout.row, actorsList);
listview.setAdapter(adapter);
} catch (Exception e) {
e.printStackTrace();
}
}
return rootView;
}
class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {
@Override
protected void onPreExecute() {
}
@Override
protected Boolean doInBackground(String... urls) {
try {
//------------------>>
HttpGet httppost = new HttpGet(urls[0]);
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httppost);
// StatusLine stat = response.getStatusLine();
int status = response.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);
JSONObject jsono = new JSONObject(data);
jarray = jsono.getJSONArray("posts");
for (int i = 0; i < jarray.length(); i++) {
JSONObject object = jarray.getJSONObject(i);
Actors actor = new Actors();
actor.setName(object.getString("title"));
actor.setDescription(object.getString("url"));
actor.setImage(object.getString("thumbnail"));
actorsList.add(actor);
}
return true;
}
} catch (ParseException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean result) {
dialog.cancel();
adapter.notifyDataSetChanged();
if (result) {
try {
dataPath = objectToFile(actorsList);
} catch (IOException e) {
e.printStackTrace();
}
} else {
Toast.makeText(getActivity().getApplicationContext(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();
}
}
}
如您所见,我正在尝试实现与上面链接的问题中所问的相同的事情,但无法弄清楚如何在离线时显示 ArrayList
。请帮忙
更新: logcat
04-21 14:23:33.161 4870-4870/info.androidhive.slidingmenu E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: info.androidhive.slidingmenu, PID: 4870
java.lang.RuntimeException: Unable to start activity ComponentInfo{info.androidhive.slidingmenu/info.androidhive.slidingmenu.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2412)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2470)
at android.app.ActivityThread.access0(ActivityThread.java:174)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1307)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5593)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at java.io.File.fixSlashes(File.java:185)
at java.io.File.<init>(File.java:134)
at info.androidhive.slidingmenu.ObjectToFileUtil.objectFromFile(ObjectToFileUtil.java:31)
at info.androidhive.slidingmenu.PagesFragment.onCreateView(PagesFragment.java:176)
at android.app.Fragment.performCreateView(Fragment.java:1700)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:890)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1062)
at android.app.BackStackRecord.run(BackStackRecord.java:684)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1453)
at android.app.Activity.performStart(Activity.java:5467)
at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2385)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2470)
at android.app.ActivityThread.access0(ActivityThread.java:174)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1307)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5593)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1283)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
at dalvik.system.NativeStart.main(Native Method)
这是将 ObjectToFile 和 ObjectFromFile 转换的 Class
package info.androidhive.slidingmenu;
import android.os.Environment;
import java.io.*;
public class ObjectToFileUtil {
public static String objectToFile(Object object) throws IOException {
String path = Environment.getExternalStorageDirectory() + File.separator + "cache" + File.separator;
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
path += "data";
File data = new File(path);
if (!data.createNewFile()) {
data.delete();
data.createNewFile();
}
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(data));
objectOutputStream.writeObject(object);
objectOutputStream.close();
return path;
}
public static Object objectFromFile(String path) throws IOException, ClassNotFoundException {
Object object = null;
File data = new File(path);
if(data.exists()) {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(data));
object = objectInputStream.readObject();
objectInputStream.close();
}
return object;
}
}
更新代码的更新答案
根据这个更改您的 ObjectToFileUtil class-
public class ObjectToFileUtil {
private static baseFilePath = Environment.getExternalStorageDirectory() + File.separator + "cache" + File.separator+"data";
public static String objectToFile(Object object) throws IOException {
String path = baseFilePath;
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
File data = new File(path);
if (!data.createNewFile()) {
data.delete();
data.createNewFile();
}
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(data));
objectOutputStream.writeObject(object);
objectOutputStream.close();
return path;
}
public static Object objectFromFile() throws IOException, ClassNotFoundException {
String path = baseFilePath;
Object object = null;
File data = new File(path);
if(data.exists()) {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(data));
object = objectInputStream.readObject();
objectInputStream.close();
}
return object;
}
然后更改以下行 -
actorsList = (ArrayList<Actors>)objectFromFile(dataPath);
到-
actorsList = (ArrayList<Actors>)objectFromFile();
问题的原因
您在网络可用时保存了文件,并将文件路径存储在 dataPath
成员中。现在,当您在没有网络可用的情况下启动应用程序时,您正在尝试打开文件,假设该文件已经具有 json。到目前为止一切都很好。但是有一个逻辑错误。当您重新启动您的应用程序时,请查看 dataPath
中没有值,尽管文件可能存在,因为 dataPath
仅在您刚刚写入文件时分配。所以你的路径是 null
并且文件对象没有在 objectFromFile()
还要确保您的 Actors
class 正在实现 Serializable
接口。导致在文件中保存一个对象然后正确地检索它,该对象需要 Serializable
.
您可以将对象数组列表转换为字符串并将其存储在 sharedprefrences 中,如下所示:-
Gson gson = new Gson();
SharedPreferences sharedPreferences= PreferenceManager.getDefaultSharedPreferences(getActivity());
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("list",gson.toJson(actorsList));
editor.commit();
然后你可以在连接不可用的 else 块中检索此列表,如下所示:-
SharedPreferences sharedPreferences= PreferenceManager.getDefaultSharedPreferences(getActivity());
String string=sharedPreferences.sharedPreferences.getString("list",null);
List<Actors> list=new List<Actors>();
Type listType = new TypeToken<ArrayList<Actors>>() {
}.getType();
list= new Gson().fromJson(string, listType);
我在这里使用 gson 来序列化和反序列化对象,并且不要忘记在您的 gradle 文件中包含 gson