5

I want to implement LoaderManager in my application in order to reduce the startup time As you can see here but after implementing the suggestion in that thread i was getting the following error initLoader(int, Bundle, LoaderManager.LoaderCallbacks) in the type LoaderManager is not applicable for the arguments (int, null, MainActivity). After searching on here i found the solution for that second error here. But after implementing the suggestion from later, now i am getting the error java.lang.NullPointerException at android.support.v4.content.Loader. I am putting up the code which i currently have, can anyone tell me, how can i solve this problem

FULL CODE CAN BE SEEN HERE

Log Cat

10-03 20:11:34.849: E/AndroidRuntime(2968): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.sms.it/com.test.sms.it.MainActivity}: java.lang.NullPointerException
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.os.Looper.loop(Looper.java:123)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.app.ActivityThread.main(ActivityThread.java:3683)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at java.lang.reflect.Method.invokeNative(Native Method)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at java.lang.reflect.Method.invoke(Method.java:507)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at dalvik.system.NativeStart.main(Native Method)
10-03 20:11:34.849: E/AndroidRuntime(2968): Caused by: java.lang.NullPointerException
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.support.v4.content.Loader.<init>(Loader.java:91)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.support.v4.content.AsyncTaskLoader.<init>(AsyncTaskLoader.java:92)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at com.test.sms.it.MainActivity$ContactsDataLoader.<init>(MainActivity.java:104)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at com.test.sms.it.MainActivity.onCreateLoader(MainActivity.java:496)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.support.v4.app.LoaderManagerImpl.createLoader(LoaderManager.java:487)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.support.v4.app.LoaderManagerImpl.createAndInstallLoader(LoaderManager.java:496)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.support.v4.app.LoaderManagerImpl.initLoader(LoaderManager.java:550)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at com.test.sms.it.MainActivity.onCreate(MainActivity.java:91)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
10-03 20:11:34.849: E/AndroidRuntime(2968):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)

MainActivity.java

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Color;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.AsyncTaskLoader;
import android.support.v4.content.Loader;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
import android.widget.Toast;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);
    editUser1UserName = (EditText) findViewById(R.id.editTextUser1UserName);
    editUser1Password = (EditText) findViewById(R.id.editTextUser1Password);
    editUser2UserName = (EditText) findViewById(R.id.editTextUser2UserName);
    editUser2Password = (EditText) findViewById(R.id.editTextUser2Password);
    editUser3UserName = (EditText) findViewById(R.id.editTextUser3UserName);
    editUser3Password = (EditText) findViewById(R.id.editTextUser3Password);
    editUser4UserName = (EditText) findViewById(R.id.editTextUser4UserName);
    editUser4Password = (EditText) findViewById(R.id.editTextUser4Password);
    editUser5UserName = (EditText) findViewById(R.id.editTextUser5UserName);
    editUser5Password = (EditText) findViewById(R.id.editTextUser5Password);
    mTxtPhoneNo = (AutoCompleteTextView) findViewById(R.id.mmWhoNo);
    mTxtPhoneNo.setThreshold(1);
    mTxtPhoneNo.setTextColor(Color.BLACK);
    editText = (EditText) findViewById(R.id.editTextMessage);
    spinner1 = (Spinner) findViewById(R.id.spinnerGateway);
    btnsend = (Button) findViewById(R.id.btnSend);
    btnContact = (Button) findViewById(R.id.btnContact);
    btnClear = (Button) findViewById(R.id.btnClear);
    btnClear.setOnClickListener(this);
    btnsend.setOnClickListener(this);
    btnContact.setOnClickListener(this);
    mPeopleList = new ArrayList<Map<String, String>>();
    getSupportLoaderManager().initLoader(0, null, this);
    mTxtPhoneNo.setOnItemClickListener(this);
    readPerson();
    Panel panel;
    topPanel = panel = (Panel) findViewById(R.id.mytopPanel);
    panel.setOnPanelListener(this);
    panel.setInterpolator(new BounceInterpolator(Type.OUT));
    getLoginDetails();
}

public class ContactsDataLoader extends
        AsyncTaskLoader<ArrayList<Map<String, String>>> {
    public ContactsDataLoader(Context context) {
        super(context);
    }

    @Override
    public ArrayList<Map<String, String>> loadInBackground() {
        mPeopleList.clear();
        Cursor people = getContentResolver().query(
                ContactsContract.Contacts.CONTENT_URI, null, null, null,
                null);
        while (people.moveToNext()) {
            String contactName = people
                    .getString(people
                            .getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
            String contactId = people.getString(people
                    .getColumnIndex(ContactsContract.Contacts._ID));
            String hasPhone = people
                    .getString(people
                            .getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));

            if ((Integer.parseInt(hasPhone) > 0)) {
                Cursor phones = getContentResolver().query(
                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        null,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID
                                + " = " + contactId, null, null);
                while (phones.moveToNext()) {
                    String phoneNumber = phones
                            .getString(phones
                                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                    String numberType = phones
                            .getString(phones
                                    .getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
                    Map<String, String> NamePhoneType = new HashMap<String, String>();
                    NamePhoneType.put("Name", contactName);
                    NamePhoneType.put("Phone", phoneNumber);
                    if (numberType.equals("0"))
                        NamePhoneType.put("Type", "Work");
                    else if (numberType.equals("1"))
                        NamePhoneType.put("Type", "Home");
                    else if (numberType.equals("2"))
                        NamePhoneType.put("Type", "Mobile");
                    else
                        NamePhoneType.put("Type", "Other");
                    mPeopleList.add(NamePhoneType);
                }
                phones.close();
            }
        }
        people.close();
        startManagingCursor(people);
        return mPeopleList;
    }

    @Override
    protected void onStartLoading() {
        super.onStartLoading();
        forceLoad();
    }
}

public Loader<ArrayList<Map<String, String>>> onCreateLoader(int id,
        Bundle args) {
    return new ContactsDataLoader(context);
}

public void onLoadFinished(Loader<ArrayList<Map<String, String>>> loader,
        ArrayList<Map<String, String>> data) {
    mPeopleList = data;
    mAdapter = new SimpleAdapter(this, mPeopleList, R.layout.custcontview,
            new String[] { "Name", "Phone", "Type" }, new int[] {
                    R.id.ccontName, R.id.ccontNo, R.id.ccontType });
    mTxtPhoneNo.setAdapter(mAdapter);
}

public void onLoaderReset(Loader<ArrayList<Map<String, String>>> loader) {
    mPeopleList = new ArrayList<Map<String, String>>();
    mAdapter = new SimpleAdapter(this, mPeopleList, R.layout.custcontview,
            new String[] { "Name", "Phone", "Type" }, new int[] {
                    R.id.ccontName, R.id.ccontNo, R.id.ccontType });
    mTxtPhoneNo.setAdapter(mAdapter);
}
Community
  • 1
  • 1
Tapan Desai
  • 848
  • 2
  • 14
  • 36
  • Check 104 line. There is something null there. – Dharmendra Oct 09 '12 at 04:52
  • have you checked arrays or any other data type ? because it is crashing due to null pointer exception, Sorry I don;t have much time to review your code. – Mudasar Oct 09 '12 at 04:53
  • @Dharmendra at line 104 this code is there `super(context);` – Tapan Desai Oct 09 '12 at 05:13
  • @Mudasar i didnt get what you are trying to say.. – Tapan Desai Oct 09 '12 at 05:14
  • In public Loader>> onCreateLoader(int id, Bundle args) { return new ContactsDataLoader(context); } Where are you getting context ? – Dharmendra Oct 09 '12 at 05:23
  • @Dharmendra in the constructor of `ContactsDataLoader` see this `public ContactsDataLoader(Context context) { super(context); } ` – Tapan Desai Oct 09 '12 at 05:52
  • @Dharmendra i told u. I am getting `Context` in the constructor of `ContactsDataLoader` class – Tapan Desai Oct 09 '12 at 05:58
  • You did not answer the question. The question is where do you get the context from, not how do you use it. You do not "get" a context in a constructor, you use it. I can't see where you are getting the context from in your code. If you put a breakpoint on that line, is context null? – Simon Oct 09 '12 at 06:09
  • That I am telling but @TapanDesai is not getting my point. – Dharmendra Oct 09 '12 at 06:13
  • I assume `context` is null here: `new ContactsDataLoader(context);` –  Oct 09 '12 at 06:28
  • @Dharmendra yes you are right. The value is not been assigned to `context`. What value should be assigned? Full code can be seen here --> http://pastebin.com/gNa3jcYW – Tapan Desai Oct 09 '12 at 09:02
  • @RC. what's the solution then? Yes null is exactly where you pointed out – Tapan Desai Oct 09 '12 at 09:04
  • Create a field of Context in your class and assign the context which you are getting in the constructor and then use that context to create the object of ContactsDataLoader class – Dharmendra Oct 09 '12 at 09:11
  • @Dharmendra can you please paste a code snippet. I am very confused – Tapan Desai Oct 09 '12 at 09:16

1 Answers1

1

RC's comment is the answer of your problem. You pass a null Context(as I don't see anywhere in the code you posted the context variable being initialized with a valid reference) to your custom loader and the code will fail with a NullPointerException. If you used my code from my previous answer then those callbacks are implemented in your Activity. In this case just pass this, the reference to your current Activity instance, to your custom loader:

public Loader<ArrayList<Map<String, String>>> onCreateLoader(int id,
        Bundle args) {
    return new ContactsDataLoader(this);
}

Also, if you close the cursor, there is no need to use startManagingCursor() for that Cursor as you might get in trouble.

user
  • 86,916
  • 18
  • 197
  • 190
  • now it says `java.lang.RuntimeException: Unable to start activity ComponentInfo java.lang.IllegalArgumentException: Object returned from onCreateLoader must not be a non-static inner member class: ContactsDataLoader android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)` – Tapan Desai Oct 09 '12 at 09:36
  • @TapanDesai The exception is pretty clear, the `ContactsDataLoader` class can't be a non static element in your activity. Make `mPeopleList` static and also add the `static` keyword for your `ContactsDataLoader` class `public class ContactsDataLoader...`. Although, another use of the `ContactsDataLoader` might be recommended. – user Oct 09 '12 at 09:39
  • i cannot add `static` keyword to the class `ContactsDataLoader` as it contains `getContentResolver()` which will give me error `Cannot make a static reference to the non-static method getContentResolver() from the type ContextWrapper` – Tapan Desai Oct 09 '12 at 09:58
  • @TapanDesai In the constructor of the `ContactsDataLoader` you have a reference to the outer activity(the `context`). Cast it to an `Activity` and then call the `getContentResolver` method on it(make it a field in your `ContactsDataLoader` class). Like this : `((Activity) context).getContentResolver()...` , then you can make it `static`. – user Oct 09 '12 at 10:03
  • if you have noticed i my `MainActivity extends FragementActivity` so does that mean i should use something like this? `((FragementActivity) context).getContentResolver()` – Tapan Desai Oct 09 '12 at 10:08
  • @TapanDesai It doesn't matter `FragmentActivity` extends `Activity` anyway. Just try any of them. – user Oct 09 '12 at 10:10
  • i tried casting it to `FragementActivity` and it worked but now another error. I have pasted log cat here ---> http://pastebin.com/RsdcVsDK – Tapan Desai Oct 09 '12 at 10:15