2016-08-28 33 views
0

我正在使用recyclerview,它从获取数据槽的AsyncTaskLoader的适配器获取其数据。一切都运行良好,直到我将屏幕从纵向旋转到横向。在这一点上,我使用.forceLoad()时会得到空指针异常。在我的asyncTaskLoader 我绝对不知道为什么fileLoader为空时调用相同的onCreate方法,无论方向,它适用于纵向和不横向。AsyncTaskLoader在屏幕旋转后未初始化

下面是代码:

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)  

在此先感谢您的帮助

回答

2

你不应该在你的onCreate()方法调用forceLoad()全部 - 它将不会被创建,直到onCreateLoader()被调用(这是在onCreate()完成后)。

根据Making Loading Data Lifecycle Aware blog post,您应该改为在AsyncTaskLoaderonStartLoading方法中调用forceLoad()。这样可以确保您的Loader已经创建并可以在您拨打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()); 
    } 
}; 
+0

谢谢,它现在的作品:) – Tomus