-1

So I'm getting this annoing nullPointerException and being new to Android I just can't figure out why.

Here's the code:

public class GetCoffeeBrandsAndSaveToDB extends Activity implements AsyncResponse {

private Gson gson = new Gson();
DatabaseHandler dbh;
Context context;

public GetCoffeeBrandsAndSaveToDB(Context context) {
    this.context = context;
}

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
     dbh = new DatabaseHandler(getApplicationContext());
}

public void getAllCoffeeBrands(){
    GetAllBrands g = new GetAllBrands("http://192.168.2.105:3000/api/", this);
g.execute();
}

@Override
public void processFinished(String output) {
    Log.d("this is output: ", "her kommer output fra GetCBandSaveToDB: " + output);



    CoffeeBrand[] cBrand = gson.fromJson(output, CoffeeBrand[].class);

    for (CoffeeBrand eachBrand : cBrand) {
        CoffeeBrand cBrandForDB = new CoffeeBrand(eachBrand.getDatabaseId(), eachBrand.getBrandName(), eachBrand.getCoffeesNeeded());
        Log.d("her er cBrandForDB", " : " + cBrandForDB.getBrandName() + " and the number: " + cBrandForDB.getCoffeesNeeded());
        dbh.addCoffeeBrand(cBrandForDB);

    }

    List<CoffeeBrand> brands = dbh.getAllCoffeeBrands();

    for (CoffeeBrand cb : brands) {
        String log = "Id: "+cb.getDatabaseId()+" ,Name: " + cb.getBrandName() + " ,coffeesNeeded: " + cb.getCoffeesNeeded();
        // Writing CoffeeBrands to log
        Log.d("Name: ", log);
    }

}

}

The problem arises at the dbh.addCoffeeBrand(cBrandForDB); My log works on cBrandForDB so I know it's not null, so I'm guessing somehow dbh is the problem?

My databasehandler constructor looks like so:

    public DatabaseHandler(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

Full logcat:

12-05 00:16:15.920 5025-5075/kasper.pagh.keebin D/full url:: http://192.168.2.105:3000/api/coffee/allbrands/
12-05 00:16:15.985 5025-5079/kasper.pagh.keebin D/full url:: http://192.168.2.105:3000/api/users/allcards
12-05 00:16:15.993 5025-5080/kasper.pagh.keebin D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true

[ 12-05 00:16:16.001  5025: 5025 D/         ]
HostConnection::get() New Host Connection established 0xaaaf1580, tid 5025
12-05 00:16:16.017 5025-5025/kasper.pagh.keebin D/this is output:: her kommer output fra GetCBandSaveToDB: [{"id":1,"brandName":"Baresso","numberOfCoffeeNeeded":10},{"id":2,"brandName":"Riccos","numberOfCoffeeNeeded":10}]
12-05 00:16:16.043 5025-5025/kasper.pagh.keebin D/her er cBrandForDB:  : Baresso and the number: 0
12-05 00:16:16.044 5025-5025/kasper.pagh.keebin D/AndroidRuntime: Shutting down VM


--------- beginning of crash
12-05 00:16:16.046 5025-5025/kasper.pagh.keebin E/AndroidRuntime: FATAL EXCEPTION: main
Process: kasper.pagh.keebin, PID: 5025
java.lang.NullPointerException: Attempt to invoke virtual method 'void kasper.pagh.keebin.DatabaseHandler.addCoffeeBrand(entity.CoffeeBrand)' on a null object reference
    at kasper.pagh.keebin.GetCoffeeBrandsAndSaveToDB.processFinished(GetCoffeeBrandsAndSaveToDB.java:53)
    at CoffeeRest.rest.GetAllBrands.onPostExecute(GetAllBrands.java:89)
    at CoffeeRest.rest.GetAllBrands.onPostExecute(GetAllBrands.java:19)
    at android.os.AsyncTask.finish(AsyncTask.java:651)
    at android.os.AsyncTask.-wrap1(AsyncTask.java)
    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
    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)

getAllBrands:

public class GetAllBrands extends AsyncTask<String, Void, String>
{
public AsyncResponse delegate = null;
private String baseUrl;

public GetAllBrands(String baseUrl, AsyncResponse delegate)
{
    this.baseUrl = baseUrl;
    this.delegate = delegate;
}


private String getBrands() throws IOException
{
    InputStream input = null;
    BufferedReader bufferedReader = null;
    StringBuilder sb = null;

    try
    {
        URL url = new URL(baseUrl + "coffee/allbrands/");
        Log.d("full url: ", url.toString());
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setReadTimeout(10000);
        connection.setConnectTimeout(15000);
        connection.setDoInput(true);
        connection.setRequestProperty("Accept", "application/json");
        connection.setRequestProperty("refreshToken", "xxxxxxxx"); //edited out
        connection.setRequestProperty("accessToken", "xxxxxxxxxxxx"); //edited out


        connection.connect();

        input = connection.getInputStream();
        bufferedReader = new BufferedReader(new InputStreamReader(input));
        sb = new StringBuilder();
        String line;
        while ((line = bufferedReader.readLine()) != null)
        {
            sb.append(line + "\n");
        }
        bufferedReader.close();
        return sb.toString();
    } finally
    {
        if (input != null)
        {
            input.close();
        }
    }
}

@Override
protected String doInBackground(String... params)
{
    try
    {
        return getBrands();
    } catch (IOException e)
    {

        e.printStackTrace();
        return null;
    }
}

@Override
protected void onPostExecute(String result)
{
    delegate.processFinished(result);
}

}

Steffen L.
  • 149
  • 2
  • 14

1 Answers1

0

Based on what I see, this class does not need to extend Activity. You seem to be expected to make a new GetCoffeeBrandsAndSaveToDB(context) (which is a very verbose name, but whatever). And it is when you do this, that onCreate is not called, and therefore dbh object is null.

So instead, I suggest this.

public class GetCoffeeBrandsAndSaveToDB implements AsyncResponse {

    private Gson gson = new Gson();
    DatabaseHandler dbh;
    Context context;

    public GetCoffeeBrandsAndSaveToDB(Context context) {
        this.context = context;
        dbh = new DatabaseHandler(context);
    }

    public void getAllCoffeeBrands(){
        GetAllBrands g = new GetAllBrands("http://192.168.2.105:3000/api/", this);
        g.execute();
    }

In related news, you should checkout Retrofit for the HTTP API calls. And maybe even alternative database solutions that allow for easy synchronization. I believe Realm is working on a sync server, but Couchbase Lite or Parse Server are all viable options depending on your hardware availability.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245