0

I looked for a couple of questions asked on Stack Overflow for sending a int to my MainActivity and displaying it on my TextView. But trying to initialize activity or context don't work.. The latest error I get is this:

FATAL EXCEPTION: AsyncTask #1 Process: com.dahlstore.jsonparsingdemo, PID: 32123 java.lang.RuntimeException: An error occurred while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:309) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) at java.util.concurrent.FutureTask.setException(FutureTask.java:223) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.app.Activity.getApplicationContext()' on a null object reference at com.dahlstore.jsonparsingdemo.JSONTask.doInBackground(JSONTask.java:63) at com.dahlstore.jsonparsingdemo.JSONTask.doInBackground(JSONTask.java:21) at android.os.AsyncTask$2.call(AsyncTask.java:295) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)  at java.lang.Thread.run(Thread.java:818)  09-17 18:31:37.015 32123-32152/com.dahlstore.jsonparsingdemo E/Surface: getSlotFromBufferLocked: unknown buffer: 0xabea80a0

Could anybody explain why I can't send my intent even though I use Activity.

/*ROW21*/      public class JSONTask extends AsyncTask<String,String, String>{

    OnDataSendToActivity dataSendToActivity;
    Activity activity;
    Intent intent;

    public JSONTask(MainActivity mainActivity) {
        dataSendToActivity = (OnDataSendToActivity)mainActivity;
    }

    public JSONTask(Activity activity){
        this.activity = activity;
    }

    @Override
    protected String doInBackground(String... params) {

        HttpURLConnection connection = null;
        BufferedReader reader = null;

        try {
            URL url = new URL(params[0]);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();

            InputStream stream = connection.getInputStream();

            reader = new BufferedReader(new InputStreamReader(stream));
            StringBuffer buffer = new StringBuffer();

            String line = "";
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            JSONObject parentObject = new JSONObject(buffer.toString());
            JSONObject query = parentObject.getJSONObject("query").optJSONObject("results").optJSONObject("channel").optJSONObject("item");
            String temperature = query.getJSONObject("condition").optString("temp");
            String text = query.getJSONObject("condition").optString("text");

            int code = query.getJSONObject("condition").optInt("code");
           **//ROW 63**  intent = new Intent(activity.getApplicationContext(),MainActivity.class); 

            intent.putExtra("code",code);

            return temperature + " °C " +" and "+ text;

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        activity.startActivity(intent);
        dataSendToActivity.sendData(result);
    }

}

MainActivity

public class MainActivity extends AppCompatActivity implements OnDataSendToActivity{

    public TextView temperatureTextView,textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        temperatureTextView = (TextView) findViewById(R.id.temperatureTextView);
        textView = (TextView) findViewById(R.id.textView);

        new JSONTask(this).execute("https://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20woeid%3D906057%20and%20u%3D%27c%27&format=json");

        Intent intent = getIntent();
        if(intent!= null) {
            int code = getIntent().getIntExtra("code", 0);
            String codeToString = String.valueOf(code);
            textView.setText(codeToString);
        } else {
            Toast.makeText(MainActivity.this, "Intent is null", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void sendData(String str) {
        temperatureTextView.setText(str);
    }
}

UPDATED JSONTASK.JAVA

public class JSONTask extends AsyncTask<String,String, String>{
    OnDataSendToActivity dataSendToActivity;
    Context context;

    // single constructor to initialize both the context and dataSendToActivity
    public JSONTask(Context context){
        this.context = context;
        dataSendToActivity = (OnDataSendToActivity) ((Activity) context);
    }

    @Override
    protected String doInBackground(String... params) {
        HttpURLConnection connection = null;
        BufferedReader reader = null;
        StringBuffer buffer = new StringBuffer();

        try {
            URL url = new URL(params[0]);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            InputStream stream = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(stream));
            String line = "";
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return buffer.toString();
    }

    @Override
    protected void onPostExecute(String result) {
        try {
            JSONObject parentObject = new JSONObject(result);
            JSONObject query = parentObject.getJSONObject("query").optJSONObject("results").optJSONObject("channel").optJSONObject("item");
            String temperature = query.getJSONObject("condition").optString("temp");
            String text = query.getJSONObject("condition").optString("text");
            int code = query.getJSONObject("condition").optInt("code");
            temperature += " °C " +" and "+ text;

            Intent intent = new Intent(context, MainActivity.class);
            intent.putExtra("code", code);
            context.startActivity(intent);
            if(dataSendToActivity != null){
                dataSendToActivity.sendData(temperature);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

UPDATED MAINACTIVITY

public class MainActivity extends AppCompatActivity implements OnDataSendToActivity{

    public TextView temperatureTextView,textView;
    Intent intent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        temperatureTextView = (TextView) findViewById(R.id.temperatureTextView);
        textView = (TextView) findViewById(R.id.textView);
        intent = getIntent();
        new JSONTask(this).execute("https://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20woeid%3D906057%20and%20u%3D%27c%27&format=json");

    }


    @Override
    public void sendData(String str) {
        temperatureTextView.setText(str);
    }
}
user3506
  • 109
  • 1
  • 12
  • Share all error log. – Ahmad Aghazadeh Sep 17 '16 at 18:20
  • I've shared it Mr. Aghazadeh. – user3506 Sep 17 '16 at 18:25
  • add Breakpoints to ` dataSendToActivity = (OnDataSendToActivity)mainActivity;` , ` dataSendToActivity = (OnDataSendToActivity)mainActivity;` and check. – Ahmad Aghazadeh Sep 17 '16 at 18:32
  • _Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.app.Activity.getApplicationContext()' on a null object reference_ – K Neeraj Lal Sep 17 '16 at 18:35
  • Mr. Aghazadeh, When not using Intent, the onPostExecute is sending the result to my MainActivity without any problems. It's only when I add the Intent function to retrieve my 'int code', that the error occurs – user3506 Sep 17 '16 at 18:39
  • why use intent when you can send your "code" value to postExecute(String result); by adding return stringCode; in your doInBackground? – user1506104 Sep 17 '16 at 18:43
  • It's a very good idea. I know and have successfully sent the "code" through my postExecute method. The problem is that a function in my MainActivity is suppose to work as an index so I can get the correct image from my drawable folder. I can't return my "code" value with the dataSendToActivity. As you can see, That's because I'm returning two strings right now (temperature and text). Intent i= getIntent(); int value= i.getIntExtra("intVariableName", 0); Drawable weatherIconDrawable = getResources().getDrawable(value); weatherIconImageView.setImageDrawable(weatherIconDrawable); – user3506 Sep 17 '16 at 18:50

3 Answers3

1

You are getting an error because your activity is null. This happends because you have two constructors.

// this is the constructor that is called
public JSONTask(MainActivity mainActivity) {
    dataSendToActivity = (OnDataSendToActivity)mainActivity;
}

// this is not called
public JSONTask(Activity activity){
    this.activity = activity;
}

So your activity variable is never initialized.

See my changes,

public class JSONTask extends AsyncTask<String,String, String>{
    OnDataSendToActivity dataSendToActivity;
    Context context;

    // single constructor to initialize both the context and dataSendToActivity
    public JSONTask(Context context){
        this.context = context;
        dataSendToActivity = (OnDataSendToActivity) ((Activity) context);
    }

    @Override
    protected String doInBackground(String... params) {
        HttpURLConnection connection = null;
        BufferedReader reader = null;
        StringBuffer buffer = new StringBuffer();

        try {
            URL url = new URL(params[0]);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            InputStream stream = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(stream));
            String line = "";
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();
            }
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return buffer.toString();
    }

    @Override
    protected void onPostExecute(String result) {
        try {
            JSONObject parentObject = new JSONObject(result);
            JSONObject query = parentObject.getJSONObject("query").optJSONObject("results").optJSONObject("channel").optJSONObject("item");
            String temperature = query.getJSONObject("condition").optString("temp");
            String text = query.getJSONObject("condition").optString("text");
            int code = query.getJSONObject("condition").optInt("code");
            temperature += " °C " +" and "+ text;

            if(dataSendToActivity != null){
                dataSendToActivity.sendData(temperature, code);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

In your MainActivity,

public class MainActivity extends AppCompatActivity implements OnDataSendToActivity {

    public TextView temperatureTextView,textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        temperatureTextView = (TextView) findViewById(R.id.temperatureTextView);
        textView = (TextView) findViewById(R.id.textView);

        new JSONTask(this).execute("https://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20woeid%3D906057%20and%20u%3D%27c%27&format=json");
    }

    @Override
    public void sendData(String str, String code) {
        temperatureTextView.setText(str);
        textView.setText(code);
    }
}

Your OnDataSendToActivity interface will become,

public interface OnDataSendToActivity {
    void sendData(String str, String code);
}
K Neeraj Lal
  • 6,768
  • 3
  • 24
  • 33
  • Thank you very much Mr. K Neeraj Lal. Unfortunately I still get two errors. The first one, is that I can't any longer return "temperature + " °C " +" and "+ text" in my postExecute method because it's void.Changing it from void to String gives me "incompatible return type". Second error: activity inside of: Intent intent = new Intent(activity, MainActivity.class); cannot be resolved as symbol when using the code above. Am I suppose to add public JSONTask(Activity activity){ this.activity = activity; } in my code? – user3506 Sep 17 '16 at 19:05
  • My bad. See the edit. Didn't use an IDE to write the code. – K Neeraj Lal Sep 17 '16 at 19:08
  • No you don't have to add that constructor. – K Neeraj Lal Sep 17 '16 at 19:11
  • Thank you again Mr. K Neeraj Lal. Now the MainActivity retrieves the intent. But there is still some issues with the code. The MainActivity starts over and over and over again like 20 times before crashing. I have updated the whole code in my question. – user3506 Sep 17 '16 at 19:22
  • 1
    Yup, with your current architecture it is expected. Just need some minor tweaks. See the edit. – K Neeraj Lal Sep 17 '16 at 19:27
  • 1
    Thank you so much for the help! I really appreciate it, Everything is working great now! – user3506 Sep 17 '16 at 19:55
0

I think the mistake is you are using getIntExtra in the Async. Instead of that use putIntExtra to save the variable in the intent.

Put is to store the value and getIntent functions are used to get the data from the intent.

Use this line,

intent = new Intent(getApplicationContext(),MainActivity.class); 

or

intent = new Intent(YourClassName.class,MainActivity.class); 
Vishal Puri
  • 823
  • 8
  • 15
  • I don't have putIntExtra as alternative. But I just changed to putExtra instead of getIntExtra and updated the error message. – user3506 Sep 17 '16 at 18:34
  • @user3506 I have edited a line in my answer. Try it. – Vishal Puri Sep 17 '16 at 18:55
  • Unfortunately neither of this worked. But thank you for your effort! – user3506 Sep 17 '16 at 19:06
  • 1
    @user3506 You are still getting NulPointerError on this line after editing? – Vishal Puri Sep 17 '16 at 19:11
  • No Mr. Puri, I used @K Neeraj Lal suggestion, and it works pretty good. I just have to find out why my application keeps restarting over and over again... Do you see the problem? (Updated code about five minutes ago) – user3506 Sep 17 '16 at 19:30
  • I didn't have the IDE to check your code at that time. (y) N Yes, great. His solution is correct. All the best – Vishal Puri Sep 18 '16 at 04:31
0

You do not really have to use intent to send your "code" to the activity. In your doInBackground, put your "code" into a string variable (you need to properly parse it) then put that string as an argument to your return.

Then in postExecute(String result), the variable result should be the value your returned from doInBackground. The dataSendToActivity.sendData(result) should work fine now.

user1506104
  • 6,554
  • 4
  • 71
  • 89
  • It's a very good idea. I know and have successfully sent the "code" through my postExecute method. The problem is that a function in my MainActivity is suppose to work as an index so I can get the correct image from my drawable folder. I can't return my "code" value with the dataSendToActivity. As you can see, That's because I'm returning two strings right now (temperature and text). Intent i= getIntent(); int value= i.getIntExtra("intVariableName", 0); Drawable weatherIconDrawable = getResources().getDrawable(value); weatherIconImageView.setImageDrawable(weatherIconDrawable); – user3506 Sep 17 '16 at 18:50
  • i see. you can totally delete intent though. then append the "code" value to your return string in doInBackground. In postExecute, you can parse the values so that code goes to textView while temperature goes to temperatureTextView. – user1506104 Sep 17 '16 at 19:05
  • 1
    and you need to check Neeraj comment, your activity reference needs fixing. – user1506104 Sep 17 '16 at 19:11