Valdemar Mokritskiy
Valdemar Mokritskiy

Reputation: 81

App crashes when calling a method in AsyncTask Android

The problem is when i call Initialize()

public void Initialize(){
        question.setText(test.get("question").get(index));
        answer_1.setText(test.get("answer_1").get(index));
        answer_2.setText(test.get("answer_2").get(index));
        answer_3.setText(test.get("answer_3").get(index));
        answer_4.setText(test.get("answer_4").get(index));
        answer_5.setText(test.get("answer_5").get(index));
        correct = test.get("answer_5").get(index);
        index++;
    }

at Sql_bridge asyncTask

@Override
    protected void onPostExecute(HashMap<String,List<String>> stringList) {
       if(!stringList.isEmpty()) {
            test test = new test();
            test.setTest(stringList);
            test.Initialize();
        }
        else
            Log.i("test","empty");
    }

The thing is that test.setTest(stringList) works fine Here is the full code test.java

package com.example.littledev.gson;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.HashMap;
import java.util.List;

public class test extends AppCompatActivity {

    private HashMap<String, List<String>> test;
    TextView question;
    Button answer_1, answer_2, answer_3, answer_4, answer_5;
    String correct;
    int index;
    int score;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        index = 0;
        score = 0;
        correct ="";
        question = (TextView) findViewById(R.id.question);
        answer_1 = (Button) findViewById(R.id.answer_1);
        answer_2 = (Button) findViewById(R.id.answer_2);
        answer_3 = (Button) findViewById(R.id.answer_3);
        answer_4 = (Button) findViewById(R.id.answer_4);
        answer_5 = (Button) findViewById(R.id.answer_5);
        Sql_bridge bridge = new Sql_bridge();
        bridge.execute("english");

    }

    public void onAnswer(View view){

        if (index == test.get("question").size()) {

            if (view.getTag().equals(correct))
                score++;
            Initialize();
        }
        else {
            //startActivity(new Intent(test.this, Result.class));
            Result result = new Result();
            result.setScore(100*score/5);
        }

    }
    public void Initialize(){
        question.setText(test.get("question").get(index));
        answer_1.setText(test.get("answer_1").get(index));
        answer_2.setText(test.get("answer_2").get(index));
        answer_3.setText(test.get("answer_3").get(index));
        answer_4.setText(test.get("answer_4").get(index));
        answer_5.setText(test.get("answer_5").get(index));
        correct = test.get("answer_5").get(index);
        index++;
    }
    public void setTest(HashMap<String, List<String>> map){
        test = map;
    }
}

Sql_bridge.java

package com.example.littledev.gson;

import android.os.AsyncTask;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


class Sql_bridge extends AsyncTask<String, Void, HashMap<String,List<String>>> {


    @Override
    protected HashMap<String,List<String>> doInBackground(String... params) {

        String reg_url = "http://e-shops.hol.es/app_test";
        String response = "";
        List<String> questions = new ArrayList<>();
        List<String> answer_1 = new ArrayList<>();
        List<String> answer_2 = new ArrayList<>();
        List<String> answer_3 = new ArrayList<>();
        List<String> answer_4 = new ArrayList<>();
        List<String> answer_5 = new ArrayList<>();
        List<String> correct = new ArrayList<>();
            try {
                URL url = new URL(reg_url);
                HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                httpURLConnection.setRequestMethod("POST");
                httpURLConnection.setDoOutput(true);
                httpURLConnection.setDoInput(true);
                OutputStream outputStream = httpURLConnection.getOutputStream();
                BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
                String data = URLEncoder.encode("test", "UTF-8") + "=" + URLEncoder.encode(params[0], "UTF-8");
                bufferedWriter.write(data);
                bufferedWriter.flush();
                bufferedWriter.close();
                outputStream.close();
                InputStream inputStream = httpURLConnection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    response += line;
                }
                bufferedReader.close();
                inputStream.close();
                httpURLConnection.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        JSONObject jsonResponse;
        try {
            jsonResponse = new JSONObject(response);
            JSONArray jsonMainNode = jsonResponse.optJSONArray("result");
            int lengthJsonArr = jsonMainNode.length();
            Log.i("test",lengthJsonArr + " length");
            for(int i=0; i < lengthJsonArr; i++)
            {
                JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
                questions.add(jsonChildNode.optString("question"));
                answer_1.add(jsonChildNode.optString("answer_1"));
                answer_2.add(jsonChildNode.optString("answer_2"));
                answer_3.add(jsonChildNode.optString("answer_3"));
                answer_4.add(jsonChildNode.optString("answer_4"));
                answer_5.add(jsonChildNode.optString("answer_5"));
                correct.add(jsonChildNode.optString("correct"));

            }

        } catch (JSONException e) {
            e.printStackTrace();
        }

        HashMap<String, List<String>> test = new HashMap<>();
        test.put("question",questions);
        test.put("answer_1",answer_1);
        test.put("answer_2",answer_2);
        test.put("answer_3",answer_3);
        test.put("answer_4",answer_4);
        test.put("answer_5",answer_5);
        test.put("correct",correct);
        return test;
    }


    @Override
    protected void onPostExecute(HashMap<String,List<String>> stringList) {
        if(!stringList.isEmpty()) {
            test test = new test();
            test.setTest(stringList);
            test.Initialize();
        }
        else
            Log.i("test","empty");
    }

}

logcat

04-09 20:15:38.832 10470-10470/com.example.littledev.gson E/AndroidRuntime: FATAL EXCEPTION: main
                                                                            Process: com.example.littledev.gson, PID: 10470
                                                                            java.lang.NullPointerException
                                                                                at com.example.littledev.gson.test.Initialize(test.java:57)
                                                                                at com.example.littledev.gson.Sql_bridge.onPostExecute(Sql_bridge.java:104)
                                                                                at com.example.littledev.gson.Sql_bridge.onPostExecute(Sql_bridge.java:25)
                                                                                at android.os.AsyncTask.finish(AsyncTask.java:632)
                                                                                at android.os.AsyncTask.access$600(AsyncTask.java:177)
                                                                                at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
                                                                                at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                at android.os.Looper.loop(Looper.java:136)
                                                                                at android.app.ActivityThread.main(ActivityThread.java:5433)
                                                                                at java.lang.reflect.Method.invokeNative(Native Method)
                                                                                at java.lang.reflect.Method.invoke(Method.java:515)
                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
                                                                                at dalvik.system.NativeStart.main(Native Method)

Upvotes: 1

Views: 219

Answers (3)

Valdemar Mokritskiy
Valdemar Mokritskiy

Reputation: 81

Thanks to @quiro i did it. I passed the context as a parameter

private Context ctx;
    Sql_bridge(Context ctx) {
        this.ctx = ctx;
    }

and then used

if(ctx instanceof Test){
                ((Test) ctx).Initialize();
            }

Thank you for the help.

Upvotes: 0

Math Addict
Math Addict

Reputation: 54

Another possibility is to provide your AsyncTask with a callback to your activity.

public class Sql_bridge extends AsyncTask<String, Void, HashMap<String,List<String>>>
{
    public interface SqlBridgeListener
    {
        /**
         * Called when your query is completed.
         * @param stringList Result list.
         */
        void onQueryCompleted(HashMap<String,List<String>> stringList);
    }

    /**
     * Store listener as a weak reference to not leak the resource.
     */
    private WeakReference<SqlBridgeListener> mListener;

    public SqlBridge(SqlBridgeListener listener)
    {
        mListener = new WeakReference<SqlBridgeListener>(listener);
    }

    @Override
    protected HashMap<String, List<String>> doInBackground(String... strings)
    {
        // Same code as your post, not shown for brevity.
    }

    @Override
    protected void onPostExecute(HashMap<String,List<String>> stringList) {
        if(!stringList.isEmpty())
        {
            SqlBridgeListener listener = mListener.get();
            if(listener != null)
            {
                // Notify listener with results.
                listener.onQueryCompleted(stringList);
            }
        }

    }
}

Then on your activity:

public class test extends AppCompatActivity implements Sql_bridge.SqlBridgeListener {

private HashMap<String, List<String>> test;
TextView question;
Button answer_1, answer_2, answer_3, answer_4, answer_5;
String correct;
int index;
int score;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_test);
    index = 0;
    score = 0;
    correct ="";
    question = (TextView) findViewById(R.id.question);
    answer_1 = (Button) findViewById(R.id.answer_1);
    answer_2 = (Button) findViewById(R.id.answer_2);
    answer_3 = (Button) findViewById(R.id.answer_3);
    answer_4 = (Button) findViewById(R.id.answer_4);
    answer_5 = (Button) findViewById(R.id.answer_5);
    // Provide activity as a listener.
    Sql_bridge bridge = new Sql_bridge(this);
    bridge.execute("english");

}

@Override
public void onQueryCompleted(HashMap<String,List<String>> stringList)
{
  // Update your views with the result.
}
// Rest of the activity not shown for brevity.

Upvotes: 0

quiro
quiro

Reputation: 357

You're trying to create an Activity using a constructor, which is not allowed. You'll always get a NullPointerException if you keep doing that, because you're Activity won't get created so the reference to the view inside the Initialize method is null. Please, take a look at how to start an Activity

What you should be doing is creating an Intent, putting the string you need in that Activity inside the Intent, then launch the Activity using context.startActivity(intent)

Upvotes: 1

Related Questions