AsyncTaskLoader not initialized after screen rotation

I am using recyclerview which is getting its data from adapter which gets data trough AsyncTaskLoader. Everything runs fine until I rotate the screen from portrait to landscape. At that point I get nullpointer exception when using .forceLoad(); on my asyncTaskLoader I have absolutelly no idea why is the fileLoader null when the same onCreate method is called regardless of orientation and it works on portrait and doesnt on landscape.

Here is the code:

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) {
}
}

here is the stacktrace:

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) 

thanks in advance for any help


You shouldn't be calling forceLoad() in your onCreate() method at all - it won't be created until onCreateLoader() is called (which is after onCreate() finishes).

As per the Making Loading Data Lifecycle Aware blog post, you should instead be calling forceLoad() in your AsyncTaskLoader 's onStartLoading method. This ensures that your Loader is created and ready to start loading before you call 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/65366.html

上一篇: onCreateOptionsMenu和onPrepareOptionsMenu不会调用方向更改

下一篇: 屏幕旋转后,AsyncTaskLoader未初始化