[英]Android onSaveInstanceState not getting class variables
我试图将我的ListView数据保存在onSaveInstanceState中。 由于某种原因,当我在onSaveInstanceState内调用类变量时,其未填充正确的数据。
public class ArtistTopTen extends Fragment {
private ListView artistTopTen;
private String artistId;
private Tracks listTracks;
private exposed.coding.android_nano.Adapters.ArtistTopTen topTenListAdapter;
private SpotifyApi spotifyApi;
private SpotifyService spotifyService;
private MusicPlayerDialogFragment musicPlayerDialogFragment;
public ArtistTopTen() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.fragment_artist_top_ten, container, false);
if(getActivity().findViewById(R.id.topten_container) == null) {
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
// Start the service
getActivity().startService(new Intent(getActivity(), Music.class));
if(savedInstanceState == null) {
try {
if (getActivity().getIntent().hasExtra("id")) {
artistId = getActivity().getIntent().getStringExtra("id");
} else {
artistId = getArguments().getString("artistid");
}
} catch (Exception e) {
Log.e("ERROR", e.toString());
}
}else {
Log.e("NOTICE", "SavedInstanceState has data");
}
if(artistId != null) {
artistTopTen = (ListView) view.findViewById(R.id.artist_top_ten);
topTenListAdapter = new exposed.coding.android_nano.Adapters.ArtistTopTen(getActivity(), listTracks);
spotifyApi = new SpotifyApi();
spotifyService = spotifyApi.getService();
SharedPreferences sharedPreferences = getActivity().getPreferences(Context.MODE_PRIVATE);
HashMap country = new HashMap<String, Object>();
if (sharedPreferences.getString("country", "us").length() != 0) {
country.put("country", sharedPreferences.getString("country", "us").toString());
} else {
country.put("country", "us");
}
spotifyService.getArtistTopTrack(artistId, country, new Callback<Tracks>() {
@Override
public void success(Tracks tracks, Response response) {
listTracks = tracks;
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
notifyAdapter();
}
});
}
@Override
public void failure(RetrofitError error) {
Toast.makeText(view.getContext(), "Somthing went wrong", Toast.LENGTH_LONG).show();
}
});
artistTopTen.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(":MediaPlayerUpdateList");
intent.putExtra("tracks", new ParcelablesTracks(listTracks, position));
getActivity().sendBroadcast(intent);
if(getActivity().findViewById(R.id.topten_container) != null) {
musicPlayerDialogFragment = new MusicPlayerDialogFragment();
musicPlayerDialogFragment.setCancelable(false);
musicPlayerDialogFragment.show(getFragmentManager(), "fragment_music_player");
}else {
intent = new Intent(getActivity(), MusicPlayerActivity.class);
intent.putExtra("returning", false);
startActivity(intent);
}
}
});
}
if(savedInstanceState != null) {
}
return view;
}
private void notifyAdapter() {
Log.e("First Track Name - SHOWING", listTracks.tracks.get(0).name);
topTenListAdapter.setListTracks(listTracks);
if(artistTopTen.getAdapter() == null) {
artistTopTen.setAdapter(topTenListAdapter);
}else {
topTenListAdapter.notifyDataSetChanged();
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
Log.e("First Track Name - NOT SHOWING", listTracks.tracks.get(0).name);
//outState.putParcelable("list", new ParcelablesTracks(listTracks, 0));
super.onSaveInstanceState(outState);
}
}
如果查看功能notifiyAdapter(),您会看到我正在打印出歌曲的名称:
Log.e("First Track Name - SHOWING", listTracks.tracks.get(0).name);
但是,当调用onSaveInstanceState时,无论何时尝试访问轨道,它都会出错:
Log.e("First Track Name - NOT SHOWING", listTracks.tracks.get(0).name);
错误:
07-16 10:12:07.759 29091-29091/exposed.coding.android_nano E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: exposed.coding.android_nano, PID: 29091
java.lang.NullPointerException: Attempt to read from field 'java.util.List kaaes.spotify.webapi.android.models.Tracks.tracks' on a null object reference
at exposed.coding.android_nano.Fragments.ArtistTopTen.onSaveInstanceState(ArtistTopTen.java:162)
at android.app.Fragment.performSaveInstanceState(Fragment.java:2198)
at android.app.FragmentManagerImpl.saveFragmentBasicState(FragmentManager.java:1605)
at android.app.FragmentManagerImpl.saveAllState(FragmentManager.java:1662)
at android.app.Activity.onSaveInstanceState(Activity.java:1367)
at android.app.Activity.performSaveInstanceState(Activity.java:1298)
at android.app.Instrumentation.callActivityOnSaveInstanceState(Instrumentation.java:1288)
at android.app.ActivityThread.callCallActivityOnSaveInstanceState(ActivityThread.java:3961)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3924)
at android.app.ActivityThread.access$900(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1309)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
我对Android开发很陌生,但是我正在使用相同的过程将数据保存到另一个片段中,并且工作正常。 我不确定这里发生了什么。
回购: https : //github.com/Bioto/Android-Nano-Degree-Project1.2
编辑:
设置列表曲目:
E/Setting listTracks﹕ ArtistTopTen{98c918d #2 id=0x7f0c0051}
onSaveInstanceState:
E/onSaveInstanceState()﹕ ArtistTopTen{3b7de284 #1 id=0x7f0c0051}
编辑:所以似乎正在发生的是正在接收响应的Fragment实例与保存其状态的那个实例不同。 这可能是由于您如何处理Spotify请求的回调。
我认为正在发生的事情的总体思路是:
因此,您实际上看到的是内存泄漏(旧的Fragment保留在该内存中,直到请求完成)。 我建议研究一下Loader
框架来处理跨配置更改的网络请求。 或者,将其放入IntentService
,在轨道加载后保留它们,并广播事件。 如果“片段”仍在附近并接收广播,则它可以加载新结果。 否则,下一次涉及onStart()或onResume()时,它可以查找任何现有结果(可能是在片段未监听时已加载的结果)。
尝试从null对象引用上的字段'java.util.List kaaes.spotify.webapi.android.models.Tracks.tracks'中读取
listTracks
为空。 因此,调用listTracks.tracks
将导致NullPointerException
。 在某些情况下, listTracks
从未分配过listTracks
(仅在您的getArtistTopTracks()
success()
方法中分配了getArtistTopTracks()
,因此,如果由于任何原因而失败,则永远不会分配它。在这种情况下,将其包装起来就足够了空检查中的一行;即:
if (listTracks != null) {
// do stuff with listTracks
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.