I have a fragment that needs to restore the its containing RecyclerView upon screen rotation. I've been using the standard procedure with onViewStateRestored() and onSaveInstantState(). However, I'm getting a null point exception when I rotate the screen. The problem arises during onCreate() as shown on my code and logcat below. Any detailed instructions on what I'm doing wrong would be greatly appreciated.
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.google.gson.Gson;
import org.json.JSONObject;
import static uk.co.my_package.weatherscan.Utils.getForecastEndPoint;
public class PlaceForecastListFragment extends Fragment {
public static final String PAGERTABTITLE = "Forecast";
private static final String CITYID = "weather_cityid";
private static final String SEVENDAYS = "7";
private static final String LIST_STATE_KEY = "list_state";
private static final String TAG = PlaceForecastListFragment.class.getSimpleName();
private LinearLayoutManager mLinearLayoutManager;
private RecyclerView mRecyclerView;
private Parcelable mListState;
private ProgressDialog pDialog;
private String mCityId;
public PlaceForecastListFragment() {
// Required empty public constructor
}
public static PlaceForecastListFragment newInstance(String cityid) {
PlaceForecastListFragment fragment = new PlaceForecastListFragment();
Bundle args = new Bundle();
args.putString(CITYID, cityid);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mCityId = getArguments().getString(CITYID);
}
if (savedInstanceState == null) {
// Shows message to user while makeJsonObjectRequest() is still running.
pDialog = new ProgressDialog(getContext());
pDialog.setMessage("Getting weather forecast...");
pDialog.setCancelable(false);
// Make JSON request
makeJsonObjectRequest(mCityId);
} else {
// Problem arises here!!!!!!!!!!!!!!!!!!!!
mLinearLayoutManager.onRestoreInstanceState(mListState);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_place_forecast_list, container, false);
if (view instanceof RecyclerView) {
Context context = view.getContext();
mRecyclerView = (RecyclerView) view;
mLinearLayoutManager = new LinearLayoutManager(context);
mRecyclerView.setLayoutManager(mLinearLayoutManager);
}
return view;
}
#Override
public void onViewStateRestored(Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
if (savedInstanceState != null) {
mListState = savedInstanceState.getParcelable(LIST_STATE_KEY);
mRecyclerView.getLayoutManager().onRestoreInstanceState(mListState);
}
}
#Override
public void onSaveInstanceState(Bundle savedInstantState) {
super.onSaveInstanceState(savedInstantState);
//mListState = mLinearLayoutManager.onSaveInstanceState();
savedInstantState.putParcelable(LIST_STATE_KEY, mRecyclerView.getLayoutManager().onSaveInstanceState());
}
// TODO CBA: Move this method to its own class and call it from here. This will be more organized.
/**
* Method to make json object request
*/
private void makeJsonObjectRequest(final String cityId) {
showpDialog();
String url = getForecastEndPoint(cityId, SEVENDAYS);
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// Log response
Log.d(TAG, response.toString());
String responseString = String.valueOf(response);
Gson gson = new Gson();
ResponseForecastConditions responseForecastConditionsObj =
gson.fromJson(responseString, ResponseForecastConditions.class);
mRecyclerView.setAdapter(new ForecastAdapter(responseForecastConditionsObj,
getContext()));
// Hide dialog after information has been requested
hidepDialog();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Warn user
Toast.makeText(getContext(),
"No internet connection", Toast.LENGTH_LONG).show();
// hide the progress dialog
hidepDialog();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(jsonObjReq);
}
/**
* Method for showing dialog
*/
private void showpDialog() {
if (!pDialog.isShowing())
pDialog.show();
}
/**
* Method for hiding dialog
*/
private void hidepDialog() {
if (pDialog.isShowing())
pDialog.dismiss();
}
}
Below is the logcat output:
03-20 16:32:40.801 6371-6405/uk.co.my_package.weatherscan E/Surface: getSlotFromBufferLocked: unknown buffer: 0xab7cfcb0
03-20 16:32:40.823 6371-6371/uk.co.my_package.weatherscan D/AndroidRuntime: Shutting down VM
03-20 16:32:40.823 6371-6371/uk.co.my_package.weatherscan E/AndroidRuntime: FATAL EXCEPTION: main
Process: uk.co.my_package.weatherscan, PID: 6371
java.lang.RuntimeException: Unable to start activity ComponentInfo{uk.co.my_package.weatherscan/uk.co.my_package.weatherscan.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.LinearLayoutManager.onRestoreInstanceState(android.os.Parcelable)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077)
at android.app.ActivityThread.-wrap15(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.LinearLayoutManager.onRestoreInstanceState(android.os.Parcelable)' on a null object reference
at uk.co.my_package.weatherscan.PlaceForecastListFragment.onCreate(PlaceForecastListFragment.java:68)
at android.support.v4.app.Fragment.performCreate(Fragment.java:1951)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1029)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1234)
at android.support.v4.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:2041)
at android.support.v4.app.Fragment.performCreate(Fragment.java:1964)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1029)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1252)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1234)
at android.support.v4.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:2041)
at android.support.v4.app.FragmentController.dispatchCreate(FragmentController.java:163)
at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:332)
at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:74)
at uk.co.my_package.weatherscan.MainActivity.onCreate(MainActivity.java:15)
at android.app.Activity.performCreate(Activity.java:6237)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4077)
at android.app.ActivityThread.-wrap15(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1350)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
03-20 16:33:58.373 6371-6378/uk.co.my_package.weatherscan W/art: Suspending all threads took: 24.263ms
03-20 16:34:04.875 6371-6378/uk.co.my_package.weatherscan W/art: Suspending all threads took: 17.116ms
03-20 16:36:28.696 6371-6378/uk.co.my_package.weatherscan W/art: Suspending all threads took: 15.452ms
03-20 16:37:40.836 6371-6371/? I/Process: Sending signal. PID: 6371 SIG: 9
mLinearLayoutManager is null in onCreate because you create it in onCreateView(). Create an instance in onCreate and reuse it in onCreateView.
I have a fragment that needs to restore the its containing
RecyclerView upon screen rotation. I've been using the standard
procedure with onViewStateRestored() and onSaveInstantState().
However, I'm getting a null point exception when I rotate the screen.
you have done it wrongly. You do not need to save layoutManager for rotation changes, just instantiate it every time. if you have any other DATA save them and use them to create your layoutManager.
Related
After scanning the QR code normally, it stops running and cannot display the scanned content.
Barcode scanner (Main2Activity.java):
package com.example.barcodescanner;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.google.zxing.Result;
import me.dm7.barcodescanner.zxing.ZXingScannerView;
public class Main2Activity extends AppCompatActivity implements ZXingScannerView.ResultHandler {
private ZXingScannerView mScannerView;
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
mScannerView = new ZXingScannerView(this); // Programmatically initialize the scanner view
setContentView(mScannerView); // Set the scanner view as the content view
}
#Override
public void onResume() {
super.onResume();
mScannerView.setResultHandler(this); // Register ourselves as a handler for scan results.
mScannerView.startCamera(); // Start camera on resume
}
#Override
public void onPause() {
super.onPause();
mScannerView.stopCamera(); // Stop camera on pause
}
#Override
public void handleResult(Result rawResult) {
// Do something with the result here
MyFragment.textViewQr.setText(rawResult.getText());
onBackPressed();
}
}
Here is my Fragment that is using the above (MyFragment.java):
package com.example.barcodescanner;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
/**
* A simple {#link Fragment} subclass.
*/
public class MyFragment extends Fragment {
public MyFragment() {
// Required empty public constructor
}
static TextView textViewQr;
Button buttonScanner;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View view = inflater.inflate(R.layout.fragment_my,container,false);
final TextView textViewQr = (TextView) view.findViewById( R.id.textViewQr );
final Button buttonScanner = (Button) view.findViewById( R.id.buttonScanner );
buttonScanner.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity( new Intent( getActivity(), Main2Activity.class ) );
}
} );
return view;
}
}
Logcat:
2020-03-13 10:54:50.267 20894-20927/com.example.Barcodescanner D/EGL_emulation: eglMakeCurrent: 0xa08052a0: ver 2 0 (tinfo 0xa0803340)
2020-03-13 10:54:52.959 20894-20894/com.example.Barcodescanner D/AndroidRuntime: Shutting down VM
--------- beginning of crash
2020-03-13 10:54:52.959 20894-20894/com.example.Barcodescanner E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.Barcodescanner, PID: 20894
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.example.Barcodescannerwith.Main2Activity.handleResult(Main2Activity.java:37)
at me.dm7.barcodescanner.zxing.ZXingScannerView$1.run(ZXingScannerView.java:164)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
After scanning the QR code normally, it stops running, and the following tips:
Barcodescanner has stopped open app again
MyFragment.textViewQr.setText(rawResult.getText());
is Null because in fragment you are initializing another TextView.
This One:-
final TextView textViewQr = (TextView) view.findViewById( R.id.textViewQr );
I have been trying to pass some downloaded content from my activity to fragment in vain. I've broken up the steps to see where the error pops up and have made a few conclusions: (i) switching between fragment and activity and vice versa works fine.
(ii) Problem arises only when I enter some data and try to pass it to the fragment from the activity using a bundle.
Here is my fragment code:
package com.antojoh.bottomnavig;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.CardView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
/**
* A simple {#link Fragment} subclass.
* Activities that contain this fragment must implement the
* {#link ShopFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {#link ShopFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class ShopFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
static ArrayList<String> arrayList = new ArrayList<String>();
static ArrayAdapter<String> arrayAdapter;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public ShopFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment ShopFragment.
*/
// TODO: Rename and change types and number of parameters
public static ShopFragment newInstance(String param1, String param2) {
ShopFragment fragment = new ShopFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_shop, container, false);
ListView listView = (ListView) view.findViewById(R.id.list);
arrayAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_checked, arrayList);
listView.setAdapter(arrayAdapter);
CardView cardView = (CardView) view.findViewById(R.id.cardView);
cardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getContext(), BarcodeActivity.class);
startActivity(intent);
}
});
Bundle bundle = this.getArguments();
if (bundle != null){
String value = bundle.getString("coder");
arrayList.add(value);
arrayAdapter.notifyDataSetChanged();
}
return view;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
Toast.makeText(context, "Shop Fragment", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
Here is my Activity Code :
package com.antojoh.bottomnavig;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Vibrator;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseArray;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import com.google.android.gms.vision.CameraSource;
import com.google.android.gms.vision.Detector;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class BarcodeActivity extends AppCompatActivity {
SurfaceView cameraPreview;
private EditText editText;
BarcodeDetector barcodeDetector;
CameraSource cameraSource;
final int RequestCameraPermissionID = 1001;
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case RequestCameraPermissionID: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
try {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
return;
}
cameraSource.start(cameraPreview.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
}
}
break;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_barcode);
editText = (EditText) findViewById(R.id.editText);
cameraPreview = (SurfaceView) findViewById(R.id.cameraPreview);
barcodeDetector = new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.UPC_A | Barcode.UPC_E | Barcode.EAN_8 | Barcode.EAN_13 | Barcode.CODE_128 | Barcode.CODE_39 | Barcode.CODE_93 | Barcode.ISBN | Barcode.ITF)
.build();
cameraSource = new CameraSource.Builder(this, barcodeDetector)
.setRequestedPreviewSize(640, 480)
.setAutoFocusEnabled(true)
.build();
cameraPreview.getHolder().addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(BarcodeActivity.this, new String[]{Manifest.permission.CAMERA}, RequestCameraPermissionID);
return;
}
try {
cameraSource.start(cameraPreview.getHolder());
}catch (IOException e){
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
cameraSource.stop();
}
});
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
#Override
public void release() {
}
#Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> qrcodes = detections.getDetectedItems();
if (qrcodes.size() != 0){
update(qrcodes.valueAt(0).rawValue);
}
}
});
}
public class DownloadTask extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... urls) {
String result="";
URL url;
HttpURLConnection urlConnection=null;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection)url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1){
char current = (char) data;
result += current;
data = reader.read();
}
return result;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
public void update(String string) {
String result = "";
DownloadTask task = new DownloadTask();
try {
result = task.execute("https://www.barcodable.com/ean/" + string).get();
} catch (Exception e) {
e.printStackTrace();
}
Pattern p = Pattern.compile("<title>UPC (.*?)</title>");
Matcher m = p.matcher(result);
while (m.find()) {
if (m.group(1) != null) {
Bundle bundle = new Bundle();
bundle.putString("coder", m.group(1));
ShopFragment shopFragment = new ShopFragment();
shopFragment.setArguments(bundle);
getSupportFragmentManager().beginTransaction().replace(R.id.cont, shopFragment).commit();
}
}
}
public void enter(View view){
update(editText.getText().toString());
}
}
And the Logcat :
08-14 14:46:03.037 5419-5460/com.antojoh.bottomnavig W/System.err: java.io.FileNotFoundException: https://www.barcodable.com/ean/9781614272137
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:250)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java)
at com.antojoh.bottomnavig.BarcodeActivity$DownloadTask.doInBackground(BarcodeActivity.java:144)
at com.antojoh.bottomnavig.BarcodeActivity$DownloadTask.doInBackground(BarcodeActivity.java:134)
at android.os.AsyncTask$2.call(AsyncTask.java:304)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
08-14 14:46:03.038 5419-5460/com.antojoh.bottomnavig W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
08-14 14:46:03.041 5419-5419/com.antojoh.bottomnavig E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.antojoh.bottomnavig, PID: 5419
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:389)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:384)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'int java.lang.CharSequence.length()' on a null object reference
at java.util.regex.Matcher.reset(Matcher.java:995)
at java.util.regex.Matcher.<init>(Matcher.java:174)
at java.util.regex.Pattern.matcher(Pattern.java:1006)
at com.antojoh.bottomnavig.BarcodeActivity.update(BarcodeActivity.java:171)
at com.antojoh.bottomnavig.BarcodeActivity.enter(BarcodeActivity.java:190)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:384)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
It was simple. The website did not accept too many requests at a time( which I did). So all i had to do was either switch to another website or wait for a specific time to gain entry for requesting access again! Thanks!
The class that I have made does not fetch data from the given URL which I have as a String. In a static initializer I make a URL from the String, and then getResponseFromHttpUrl method should have returned the JSON data as a String. However my Log.d("jsondata") don't show anything at all and my app crashes.
package com.example.android.bakingapp;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;
public class RecipeJson {
public static final String url = "https://d17h27t6h515a5.cloudfront.net/topher/2017/May/59121517_baking/baking.json";
public static URL urlBuilt;
public static String jsonData;
static {
try {
urlBuilt = buildUrl();
jsonData = getResponseFromHttpUrl(urlBuilt);
Log.d("jsondata", jsonData);
} catch (Exception e) {
e.printStackTrace();
}
}
public static URL buildUrl() throws java.net.MalformedURLException {
return new URL(url);
}
public static String getResponseFromHttpUrl(URL url) throws IOException {
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
try {
InputStream in = urlConnection.getInputStream();
Scanner scanner = new Scanner(in);
scanner.useDelimiter("\\A");
boolean hasInput = scanner.hasNext();
if (hasInput) {
return scanner.next();
} else {
return null;
}
} finally {
urlConnection.disconnect();
}
}
}
Here are the app logs:
08-07 20:59:54.776 26319-26319/com.example.android.bakingapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.bakingapp, PID: 26319
java.lang.ExceptionInInitializerError
at com.example.android.bakingapp.RecipeListFragment.onCreateView(RecipeListFragment.java:68)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2346)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1428)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1759)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1827)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:797)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2596)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2383)
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2338)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2245)
at android.support.v4.app.FragmentManagerImpl.dispatchStateChange(FragmentManager.java:3248)
at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:3200)
at android.support.v4.app.FragmentController.dispatchActivityCreated(FragmentController.java:195)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:597)
at android.support.v7.app.AppCompatActivity.onStart(AppCompatActivity.java:177)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1382)
at android.app.Activity.performStart(Activity.java:7151)
at android.app.ActivityThread.handleStartActivity(ActivityThread.java:2949)
at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:194)
at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:180)
at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:157)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:72)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1800)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6649)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116)
at org.json.JSONTokener.nextValue(JSONTokener.java:94)
at org.json.JSONArray.<init>(JSONArray.java:92)
at org.json.JSONArray.<init>(JSONArray.java:108)
at com.example.android.bakingapp.dummy.DummyContent.makeJsonArray(DummyContent.java:55)
at com.example.android.bakingapp.dummy.DummyContent.<clinit>(DummyContent.java:28)
The culprit is this line:
jsonArray = new JSONArray(RecipeJson.jsonData);
Which means the problem is really with my class. But what is the source of the problem?
Edit: Here is the RecipeListFragment code
package com.example.android.bakingapp;
import android.content.Context;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.android.bakingapp.dummy.DummyContent;
import com.example.android.bakingapp.dummy.DummyContent.DummyItem;
/**
* A fragment representing a list of Items.
* <p/>
* Activities containing this fragment MUST implement the {#link OnListFragmentInteractionListener}
* interface.
*/
public class RecipeListFragment extends Fragment {
private static final String ARG_COLUMN_COUNT = "column-count";
int dp;
private int mColumnCount = 1;
private OnListFragmentInteractionListener mListener;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public RecipeListFragment() {
}
public static RecipeListFragment newInstance(int columnCount) {
RecipeListFragment fragment = new RecipeListFragment();
Bundle args = new Bundle();
args.putInt(ARG_COLUMN_COUNT, columnCount);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Configuration config = getResources().getConfiguration();
dp = config.smallestScreenWidthDp;
if (dp < 600) mColumnCount = 1;
else mColumnCount = 3;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_recipelist_list, container, false);
// Set the adapter
if (view instanceof RecyclerView) {
Context context = view.getContext();
RecyclerView recyclerView = (RecyclerView) view;
if (mColumnCount <= 1) {
recyclerView.setLayoutManager(new LinearLayoutManager(context));
} else {
recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
}
recyclerView.setAdapter(new MyRecipeListRecyclerViewAdapter(DummyContent.ITEMS, mListener));
}
return view;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnListFragmentInteractionListener) {
mListener = (OnListFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnListFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnListFragmentInteractionListener {
void onListFragmentInteraction(DummyItem item);
}
}
what im trying to do right now is trying to grab a location object that is already in my firebase database eg: Artic base and store it in the localeobj i created but for some reason when i run the program it keeps saying localeobj is null am i doing my listener correctly?
package com.example.spy;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.Random;
import android.content.Intent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
public class GameJoin extends AppCompatActivity implements View.OnClickListener {
private FirebaseDatabase database;
private DatabaseReference myRef;
private FirebaseUser user;
private TextView location;
private TextView role;
private TextView desc;
private Button back;
private Intent extra;
private Bundle data;
private String spy;
private Location localeObj;
private String game_code;
private Random rand;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
rand = new Random();
//Firebase stuff
user = FirebaseAuth.getInstance().getCurrentUser();
database = FirebaseDatabase.getInstance();
myRef = database.getReference();
//Views
role = (TextView) findViewById(R.id.label_role);
location = (TextView) findViewById(R.id.label_location);
desc = (TextView) findViewById(R.id.descriptionText);
//Buttons
back = (Button) findViewById(R.id.button3);
//Attach a listener to the button
findViewById(R.id.button3).setOnClickListener(this);
//Retrieve data from previous activity
extra = getIntent();
data = extra.getBundleExtra("game_data");
game_code = data.getString("game_code");
//TODO: Pull location object from Firebase
myRef.child("lobby").child(game_code).child("location").addValueEventListener( new ValueEventListener() {
#Override
public void onCancelled(DatabaseError error) {
System.out.println("************************IN CANCELLED*************************************");
}
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("************************OUTSIDE IF*************************************");
for (DataSnapshot data : dataSnapshot.getChildren()) {
localeObj = dataSnapshot.getValue(Location.class);
System.out.println("************************IN IF*************************************");
}
}
});
myRef.child("lobby").child(game_code).child("spy").addValueEventListener( new ValueEventListener() {
#Override
public void onCancelled(DatabaseError error) {
}
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot data : dataSnapshot.getChildren()) {
spy = (String) dataSnapshot.getValue(String.class);
}
}
});
//Display a special UI if the user is a spy
if (user.getEmail().equals(spy)) {
role.setText("You are the spy. Don't get caught!");
location.setText("Mystery Location");
desc.setText("Welcome to Spy Fall. Keep your identity hidden for the length of the game, or figure out what the location is to win the game.");
} else {
role.setText(localeObj.getRole(rand.nextInt(3)));
location.setText(localeObj.getLocationName());
desc.setText("Welcome to Spy Fall. Infer who is the spy before time runs out in order to win the game.");
}
}
#Override
public void onClick(View v) {
//Stuff happens when buttons are clicked
int id = v.getId();
if (id == R.id.button3) {
//Clean up old game lobby information
myRef = database.getReference("lobby");
myRef.child(game_code).child("players").child(user.getUid()).removeValue(); //Remove all data associated with the current game
//Return to the main lobby
Intent main_lobby = new Intent(GameJoin.this, MainActivity.class);
startActivity(main_lobby);
}
}
}
Here is the tomcat message i get too
--------- beginning of crash
05-09 11:01:42.718 3083-3083/com.example.spy E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.spy, PID: 3083
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.spy/com.example.spy.GameJoin}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.spy.Location.getRole(java.lang.Integer)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.spy.Location.getRole(java.lang.Integer)' on a null object reference
at com.example.spy.GameJoin.onCreate(GameJoin.java:112)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
https://gyazo.com/2b0c1ee92f365f06b1737c99793c96b3
ive posted how my database structure looks like too
If you want to get the locationName please use the following code:
myRef.child("lobby").child(game_code).child("location").addValueEventListener( new ValueEventListener() {
#Override
public void onCancelled(DatabaseError error) {
System.out.println("************************IN CANCELLED*************************************");
}
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println("************************OUTSIDE IF*************************************");
String locationName = (String) dataSnapshot.child("locationName").getValue();
}
})
Hope it helps.
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());
}
};