屏幕旋转后,AsyncTaskLoader未初始化
我正在使用recyclerview,它从获取数据的适配器获取其数据通过AsyncTaskLoader。 一切都运行良好,直到我将屏幕从纵向旋转到横向。 在这一点上,我使用.forceLoad()时会得到空指针异常。 在我的asyncTaskLoader我绝对不知道为什么是fileLoader null时调用相同的onCreate方法,无论方向,它适用于纵向和不横向。
代码如下:
package sk.tomus.filescoper;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.preference.PreferenceManager;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import java.io.File;
import java.util.ArrayList;
mport java.util.List;
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<File>> {
private android.support.v4.content.AsyncTaskLoader<List<File>> fileLoader;
private DirectoryManager directoryManager;
private RecyclerView recyclerView;
private FileRecyclerAdapter recyclerAdapter;
private RecyclerView.LayoutManager layoutManager;
private boolean isLandscape;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
directoryManager = new DirectoryManager(prefs.getString("PREFERENCE_EDIT_DEF_FOLDER", "/"));
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
isLandscape = getResources().getBoolean(R.bool.isLandscape);
if (isLandscape) {
layoutManager = new GridLayoutManager(this, 4);
} else {
layoutManager = new LinearLayoutManager(this);
}
recyclerView.setLayoutManager(layoutManager);
recyclerAdapter = new FileRecyclerAdapter(new ArrayList<File>());
getSupportLoaderManager().initLoader(0, null, this);
//below is line 51 where the code crashes
fileLoader.forceLoad();
recyclerView.setAdapter(recyclerAdapter);
}
@Override
protected void onResume() {
super.onResume();
recyclerAdapter.setOnItemClickListener(new FileRecyclerAdapter.MyClickListener() {
@Override
public void onItemClick(int position, View v) {
Log.i("LOG", " Clicked on Item " + position);
}
});
}
private void onFileClicked(File file) {
if (file.isDirectory()) {
Log.i("opening directory", file.getAbsolutePath());
if (!file.canRead()) {
Toast.makeText(getApplicationContext(), "inaccessible", Toast.LENGTH_SHORT).show();
return;
}
directoryManager.setPreviousDir(directoryManager.getCurrentDir());
directoryManager.setCurrentDir(file);
if (fileLoader.isStarted()) {
fileLoader.onContentChanged();
}
} else {
openFile(Uri.fromFile(file));
}
}
private void openFile(Uri fileUri) {
String mimeType = directoryManager.getMimeType(fileUri);
if (mimeType != null) {
try {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setDataAndType(fileUri, mimeType);
startActivity(i);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, "file type recognized, but no apps to open it", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(this, "unknown file type", Toast.LENGTH_LONG).show();
}
}
@Override
public Loader<List<File>> onCreateLoader(int i, Bundle bundle) {
fileLoader = new android.support.v4.content.AsyncTaskLoader<List<File>>(this) {
@Override
public List<File> loadInBackground() {
Log.i("loader loading:", directoryManager.getCurrentDir().toString());
return directoryManager.getAllFiles(directoryManager.getCurrentDir());
}
};
return fileLoader;
}
@Override
public void onLoadFinished(Loader<List<File>> loader, List<File> data) {
recyclerAdapter.setFiles(data);
}
@Override
public void onLoaderReset(Loader<List<File>> loader) {
}
}
这里是堆栈跟踪:
08-29 00:50:21.176 16411-16411/sk.tomus.filescoper E/AndroidRuntime: FATAL EXCEPTION: main
Process: sk.tomus.filescoper, PID: 16411
java.lang.RuntimeException: Unable to start activity ComponentInfo{sk.tomus.filescoper/sk.tomus.filescoper.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.content.AsyncTaskLoader.forceLoad()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4053)
at android.app.ActivityThread.access$900(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1357)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5389)
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:1020)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.content.AsyncTaskLoader.forceLoad()' on a null object reference
at sk.tomus.filescoper.MainActivity.onCreate(MainActivity.java:51)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2332)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2442)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4053)
at android.app.ActivityThread.access$900(ActivityThread.java:156)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1357)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5389)
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:1020)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:815)
在此先感谢您的帮助
你不应该在你的onCreate()
方法中调用forceLoad()
- 直到onCreateLoader()
被调用( onCreate()
完成后onCreateLoader()
才会被创建。
根据制作加载数据生命周期的博客帖子,您应该改为在AsyncTaskLoader
的onStartLoading
方法中调用forceLoad()
。 这可以确保在调用forceLoad()
之前创建加载器并准备开始加载。
fileLoader = new android.support.v4.content.AsyncTaskLoader<List<File>>(this) {
@Override
public void onStartLoading() {
forceLoad();
}
@Override
public List<File> loadInBackground() {
Log.i("loader loading:", directoryManager.getCurrentDir().toString());
return directoryManager.getAllFiles(directoryManager.getCurrentDir());
}
};
链接地址: http://www.djcxy.com/p/65365.html