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)
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)
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.
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.
Related
I'm building an android app where in this section it pulls data from sql database as per the logged in userId(memberNo) which is passed through Bundle and shows it on a RecyclerView but i get this error:
2022-03-31 14:09:41.027 9620-9667/com.dennisky.kofee E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2
Process: com.dennisky.kofee, PID: 9620
java.lang.RuntimeException: An error occurred while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:353)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
at java.util.concurrent.FutureTask.run(FutureTask.java:271)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.util.NoSuchElementException
at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:759)
at java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:780)
at com.dennisky.kofee.MedicalFeesReports$RepData.packReportData(MedicalFeesReports.java:76)
at com.dennisky.kofee.MedicalFeesReports$MedicalReportDownloader.reportData(MedicalFeesReports.java:153)
at com.dennisky.kofee.MedicalFeesReports$MedicalReportDownloader.doInBackground(MedicalFeesReports.java:126)
at com.dennisky.kofee.MedicalFeesReports$MedicalReportDownloader.doInBackground(MedicalFeesReports.java:98)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
The Code that is executed when the error occurs is:
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.dennisky.kofee.MedicalFeesReport.Parser;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
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.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.util.Iterator;
public class MedicalFeesReports extends AppCompatActivity {
RecyclerView recyclerView;
String ulrAddress = "http://10.0.2.2/important/loan_statements";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_medical_fees_reports);
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setItemAnimator(new DefaultItemAnimator());
new MedicalReportDownloader(MedicalFeesReports.this, ulrAddress, recyclerView).execute();
}
public String reportNumber() {
String member = null;
Bundle extra = getIntent().getExtras();
if (extra != null) {
member = extra.getString("memberNo");
}
return member;
}
public class RepData {
public String packReportData() {
JSONObject jo = new JSONObject();
StringBuffer jsonData = new StringBuffer();
try {
jo.put("MEMBER_NO", reportNumber());
Boolean isFirstValue = true;
Iterator it = jo.keys();
do {
String keys = it.next().toString();
String values = jo.get(keys).toString();
if (isFirstValue)
isFirstValue = false;
else
jsonData.append("&");
jsonData.append(URLEncoder.encode(keys, "UTF-8"));
jsonData.append("=");
jsonData.append(URLEncoder.encode(values, "UTF-8"));
} while (it.hasNext());
return jsonData.toString();
} catch (JSONException e) {
e.printStackTrace();
return "ERROR: DATA ERROR";
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return "ERROR: ERROR ENCODING DATA";
}
}
}
public class MedicalReportDownloader extends AsyncTask<Void, Void, String> {
Context context;
String urlAddress;
RecyclerView recyclerView;
ProgressDialog dialog;
public MedicalReportDownloader(Context context, String urlAddress, RecyclerView recyclerView) {
this.context = context;
this.urlAddress = urlAddress;
this.recyclerView = recyclerView;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(context);
dialog.setTitle("Loading");
dialog.setMessage("fetching data, please wait...");
if (isFinishing() && dialog != null)
dialog.show();
}
#Override
protected String doInBackground(Void... voids) {
return this.repData();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
dialog.dismiss();
if (s != null) {
Parser parser = new Parser(s, context, recyclerView);
parser.execute();
} else {
Toast.makeText(context, "No loan data found", Toast.LENGTH_SHORT).show();
}
}
private String repData() {
Object connection = Connector.connect(urlAddress);
if (connection.toString().startsWith("Error"))
return connection.toString();
try {
HttpURLConnection con = (HttpURLConnection) connection;
OutputStream stream = new BufferedOutputStream(con.getOutputStream());
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(stream));
String kiloData = new RepData().packReportData();
if (kiloData.startsWith("ERROR"))
return "ERROR: DATA ERROR";
writer.write(kiloData);
writer.flush();
writer.close();
InputStream inputStream = new BufferedInputStream(con.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
StringBuffer buffer = new StringBuffer();
if (bufferedReader != null) {
while ((line = bufferedReader.readLine()) != null)
buffer.append(line + "\n");
} else
return null;
return buffer.toString();
} catch (IOException e) {
e.printStackTrace();
}
return "ERROR: IO ERROR";
}
}
}
the mentioned parser class:
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;
import androidx.recyclerview.widget.RecyclerView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class Parser extends AsyncTask<Void, Void, Integer> {
String data;
Context context;
RecyclerView recyclerView;
ProgressDialog dialog;
ArrayList<ReportData> reportData = new ArrayList<>();
MyAdapterMedicalReport adapter;
public Parser(String data, Context context, RecyclerView recyclerView) {
this.data = data;
this.context = context;
this.recyclerView = recyclerView;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(context);
dialog.setTitle("Parsing data");
dialog.setMessage("Data parsing, please wait...");
dialog.show();
}
#Override
protected Integer doInBackground(Void... voids) {
return this.parse();
}
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
if (dialog != null && dialog.isShowing()){
dialog.dismiss();
dialog = null;
}
if (integer == 1){
adapter = new MyAdapterMedicalReport(context, reportData);
recyclerView.setAdapter(adapter);
}else
Toast.makeText(context, "No Loan data found.", Toast.LENGTH_LONG).show();
}
private int parse(){
try {
JSONArray jsonArray = new JSONArray(data);
JSONObject jsonObject = null;
reportData.clear();
ReportData data = null;
for (int i = 0; i<jsonArray.length(); i++){
jsonObject = jsonArray.getJSONObject(i);
String loan_type = jsonObject.getString("loan_type");
String amount = jsonObject.getString("amount");
String data_approved = jsonObject.getString("date_approved");
String loan_status = jsonObject.getString("loan_status");
data = new ReportData();
data.setLoanType(loan_type);
data.setAmount(amount);
data.setDateApproved(data_approved);
data.setLoanStatus(loan_status);
reportData.add(data);
}
return 1;
} catch (JSONException e) {
e.printStackTrace();
}
return 0;
}
}
How can i get through this error?
In your "packReportData()" method you're doing a "do..while" but you need to check if "it.hasNext() == true" BEFORE "it.next()" or it will crash as you saw.
Please convert "do...while" in a "while(it.hasNext()) {...}"
When I navigate to the activity that should load a ListView from a JSON hosted on AWS S3, I get nothing but a blank activity. There's no error message, no errors in the debugger, and Logcat doesn't seem to hold any relevant information.
Here's LoadJSONTask.java:
package com.teamplum.projectapple;
import android.os.AsyncTask;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.teamplum.projectapple.NewsDO;
import com.teamplum.projectapple.Response;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
public class LoadJSONTask extends AsyncTask<String, Void, Response> {
public LoadJSONTask(Listener listener) {
mListener = listener;
}
public interface Listener {
void onLoaded(List<NewsDO> androidList);
void onError();
}
private Listener mListener;
#Override
protected Response doInBackground(String... strings) {
try {
String stringResponse = loadJSON(strings[0]);
Gson gson = new Gson();
return gson.fromJson(stringResponse, Response.class);
} catch (IOException e) {
e.printStackTrace();
return null;
} catch (JsonSyntaxException e) {
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(Response response) {
if (response != null) {
mListener.onLoaded(response.getAndroid());
} else {
mListener.onError();
}
}
private String loadJSON(String jsonURL) throws IOException {
URL url = new URL(jsonURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
StringBuilder response = new StringBuilder();
while ((line = in.readLine()) != null) {
response.append(line);
}
in.close();
return response.toString();
}
}
and here's MainActivity.java:
package com.teamplum.projectapple;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
//import com.teamplum.projectapple.NewsDO;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MainActivity extends AppCompatActivity implements LoadJSONTask.Listener, AdapterView.OnItemClickListener {
private ListView mListView;
public static final String URL = "https://s3-eu-west-1.amazonaws.com/tyi-work/Work_Experience.json";
private List<HashMap<String, String>> mAndroidMapList = new ArrayList<>();
private static final String KEY_TIT = "title";
private static final String KEY_CAT = "category";
private static final String KEY_DES = "description";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mListView = findViewById(R.id.list_view);
mListView.setOnItemClickListener(this);
new LoadJSONTask(this).execute(URL);
}
#Override
public void onLoaded(List<NewsDO> androidList) {
for (NewsDO work : androidList) {
HashMap<String, String> map = new HashMap<>();
map.put(KEY_TIT, work.getTitle());
map.put(KEY_CAT, work.getCategory());
map.put(KEY_DES, work.getDescription());
mAndroidMapList.add(map);
}
loadListView();
}
#Override
public void onError() {
Toast.makeText(this, "Error !", Toast.LENGTH_SHORT).show();
}
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(this, mAndroidMapList.get(i).get(KEY_TIT),Toast.LENGTH_LONG).show();
}
private void loadListView() {
ListAdapter adapter = new SimpleAdapter(MainActivity.this, mAndroidMapList, R.layout.list_item,
new String[] { KEY_CAT, KEY_TIT, KEY_DES },
new int[] { R.id.version,R.id.name, R.id.api });
mListView.setAdapter(adapter);
}
}
I used this tutorial to help make this, if you need any extra information please feel free to ask, thank you.
I have tested the async task for the URL connection and its working fine.
The problem is either on the parsing or on the activity side. Have you tried putting breakpoints and follow the data?
This is what I essentially want to do, but can't. I want the value of urlData and size to be updated from the inner class functions. The app is crashing by giving a Null Pointer Exception at the line where I try to access these variables from the CreateTextView() function.
package edu.ahduni.seas.gyapak;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import org.json.JSONException;
import org.json.JSONArray;
import org.json.JSONObject;
import android.util.Log;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
public ArrayList<Data> urlData; //Culprit 1
public int size; //no. of dirs + files, Culprit 2
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void parseJSON() throws JSONException {
ParseActivity parse = new ParseActivity();
String url = "RDovQWNhZGVtaWMvU2FuamF5IENoYXVkaGFyeQ==";
parse.execute(url);
CreateTextView();
Log.e("RETURNING JSON","RETURNING");
}
public void CreateTextView() {
TextView text = (TextView) findViewById(R.id.text);
text.setText(Integer.toString(size));
Button myButton = new Button(this);
if(urlData==null) //workaround for crash
return;
myButton.setText(urlData.get(0).getName());
LinearLayout ll = (LinearLayout)findViewById(R.id.textlayout);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
ll.addView(myButton, lp);
}
class ParseActivity extends AsyncTask<String, Void, ArrayList<Data>> {
InputStream is = null;
JSONArray jObj = null;
String json = "";
#Override
public void onPostExecute(ArrayList<Data> data) {
size = data.size(); //here!
}
#Override
protected ArrayList<Data> doInBackground(String... params) {
final String BASE_URL = "http://111.93.66.162/json/main.php?f=" + params[0];
HttpURLConnection urlConnection;
// Making HTTP request
try {
Log.e("OPENING: ", "URL");
URL url = new URL(BASE_URL);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
is = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (is == null) {
// Nothing to do.
return null;
}
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = in.readLine()) != null) {
buffer.append(line + "\n");
Log.e("JSON: ", line);
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
is.close();
json = buffer.toString();
} catch (Exception e) {
e.printStackTrace();
}
try {
return getData(json);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
public ArrayList<Data> getData(String jsonString) throws JSONException {
// try parse the string to a JSON object
final String EXT = "ext";
final String PATH = "path";
final String NAME = "name";
try {
jObj = new JSONArray(jsonString);
} catch (JSONException e) {
e.printStackTrace();
}
urlData = new ArrayList<Data>();
for (int i=0;i<jObj.length();i++) {
JSONObject obj = jObj.getJSONObject(i);
String ext = obj.getString(EXT);
String path = obj.getString(PATH);
String name = obj.getString(NAME);
urlData.add(new Data(ext,path,name)); //and here!
}
return urlData;
}
}
}
The inner class is not static, so it needs an instance of the enclosing class to be instantiated. Like so:
public class abcd {
static int x;
public static void main(String[] args) {
abcd o = new abcd(); // Create instance of abcd called 'o'
abcd.efgh o2 = o.new efgh(); // Use instance 'o' to create an instance of efgh
System.out.println(x); // 0
o2.ok();
System.out.println(x); // 5
}
class efgh {
public void ok() {
x = 5;
}
}
}
What I want to achieve is the following:
In my view, I have 4 TextViews that should show the amount of items in the connected databases. This is done using a simple php script.
The problem I have is that I get all the correct values from the database, but when I try to set those values to my TextViews, the app crashes.
I have tried to look if using to many Asynctasks could be a problem, but when I decide to comment out the only line inside the SetTextForTextView() function, it all works like a charm and all the expected values are printed to my log. So with that being said, I dont think using multiple Asynctasks at the same time is the problem here, but I have really no idea what is.
Something that might be worth mentioning is when I comment out the following bit like this, the app doesn't crash...
shoesAmount = (TextView) findViewById(R.id.menuTvShoesAmount);
DatabaseTask taskA = new DatabaseTask(shoesAmount);
taskA.execute("getAmount", "shoes");
// tshirtsAmounts = (TextView) findViewById(R.id.menuTvTshirtsAmount);
// DatabaseTask taskB = new DatabaseTask(tshirtsAmounts);
// taskB.execute("getAmount", "tshirts");
//
// jeansAmount = (TextView) findViewById(R.id.menuTvJeansAmount);
// DatabaseTask taskC = new DatabaseTask(jeansAmount);
// taskC.execute("getAmount", "jeans");
//
// blousesAmount = (TextView) findViewById(R.id.menuTvBlousesAmount);
// DatabaseTask taskD = new DatabaseTask(blousesAmount);
// taskD.execute("getAmount", "blouses");
But then again with any other combination for example like this one, and the app crashes again...
// shoesAmount = (TextView) findViewById(R.id.menuTvShoesAmount);
// DatabaseTask taskA = new DatabaseTask(shoesAmount);
// taskA.execute("getAmount", "shoes");
//
tshirtsAmounts = (TextView) findViewById(R.id.menuTvTshirtsAmount);
DatabaseTask taskB = new DatabaseTask(tshirtsAmounts);
taskB.execute("getAmount", "tshirts");
//
// jeansAmount = (TextView) findViewById(R.id.menuTvJeansAmount);
// DatabaseTask taskC = new DatabaseTask(jeansAmount);
// taskC.execute("getAmount", "jeans");
//
// blousesAmount = (TextView) findViewById(R.id.menuTvBlousesAmount);
// DatabaseTask taskD = new DatabaseTask(blousesAmount);
// taskD.execute("getAmount", "blouses");
Does anyone can point me out into the direction where I might be going wrong?
Thanks!
(here is the full code)
package ishopper.theindiestudio.com.appname;
import android.app.AlertDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
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.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
public class Menu extends AppCompatActivity {
private ImageButton btnHelp, btnAccount, newest1, newest2, newest3;
private TextView shoesAmount, tshirtsAmounts, jeansAmount, blousesAmount;
private Button browseShoes, browseTshirts, browseJeans, browseBlouses;
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu);
context = this;
btnHelp = (ImageButton) findViewById(R.id.menuBtnHelp);
btnAccount = (ImageButton) findViewById(R.id.menuBtnAccount);
btnAccount.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onAccountOptions();
}
});
btnHelp.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onHelp();
}
});
newest1 = (ImageButton) findViewById(R.id.menuIbNewest1);
newest2 = (ImageButton) findViewById(R.id.menuIbNewest2);
newest3 = (ImageButton) findViewById(R.id.menuIbNewest3);
//set newest items
shoesAmount = (TextView) findViewById(R.id.menuTvShoesAmount);
DatabaseTask taskA = new DatabaseTask(shoesAmount);
taskA.execute("getAmount", "shoes");
tshirtsAmounts = (TextView) findViewById(R.id.menuTvTshirtsAmount);
DatabaseTask taskB = new DatabaseTask(tshirtsAmounts);
taskB.execute("getAmount", "tshirts");
jeansAmount = (TextView) findViewById(R.id.menuTvJeansAmount);
DatabaseTask taskC = new DatabaseTask(jeansAmount);
taskC.execute("getAmount", "jeans");
blousesAmount = (TextView) findViewById(R.id.menuTvBlousesAmount);
DatabaseTask taskD = new DatabaseTask(blousesAmount);
taskD.execute("getAmount", "blouses");
}
public void SetTextForTextView(TextView textview, String result){
textview.setText(result);
}
public void onAccountOptions () {
Intent i = new Intent(this, AccountDetailsActivity.class);
startActivity(i);
}
public void onHelp () {
}
public void onBackPressed() {
//disabled back button
}
private class DatabaseTask extends AsyncTask<String, Void, String> {
private String taskType;
private String productType;
private TextView textView;
private ImageButton imageButton;
DatabaseTask (TextView mTextView){textView = mTextView;}
#Override
protected String doInBackground(String... params) {
String task = params[0];
if (task.equals("getAmount")) {
Log.e("doInBg", "getAmount");
String login_url = "http://url.eu/directory/script.php";
String tProductType = params[1];
try {
URL url = new URL(login_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 postData = URLEncoder.encode("producttable", "UTF-8") + "=" + URLEncoder.encode(tProductType, "UTF-8");
bufferedWriter.write(postData);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
String result = "";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
Log.e("doInBgResult", result.toString());
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
Menu activity = (Menu) context;
activity.SetTextForTextView(textView, result.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
}
The AsyncTask's doInBackground() runs in another thread and you can't change the UI from another thread, Only the main one. I suggest you do the same job in onPostExecute() after you finish your long job. Return the String result you want to use to the main thread
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
// no need for that
//Menu activity = (Menu) context;
//activity.SetTextForTextView(textView, result.toString());
reutrn result;
then update the text
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(result != null){
SetTextForTextView(textView, result);
}
}
I suggest reading more about it from here and here
I have an app I am trying to pass data through an ASYNC task but am getting a null pointer error in my onPosteExecute method. Seems like no matter how I change my code I still get this same fatal error:
10-31 18:43:56.517 1253-1253/com.brianstacks.project1 E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.brianstacks.project1, PID: 1253
java.lang.NullPointerException
at com.brianstacks.project1.MainActivity$MyTask.onPostExecute(MainActivity.java:277)
at com.brianstacks.project1.MainActivity$MyTask.onPostExecute(MainActivity.java:247)
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:5001)
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:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Here is my code:
MainActivity.java
public class MainActivity extends ListActivity implements MasterFragment.OnListItemClickListener {
final String Tag = "Project 1 test";
EditText myEdit;
Button myButton;
ProgressBar pb;
SerialCustomObject myObject;
// create a reference to the list's needed for data
List<MyTask> tasks;
ArrayList<Places> placeList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if ((savedInstanceState != null)&& (savedInstanceState.getSerializable("name") != null)) {
Places name = (Places) savedInstanceState.getSerializable("name");
Log.v("name:",name.getName());
}
//initiate my tasks
tasks = new ArrayList<>();
pb = (ProgressBar)findViewById(R.id.progressBar);
myEdit = (EditText)findViewById(R.id.myEditText);
myButton = (Button)findViewById(R.id.myButton);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
return id == R.id.action_settings || super.onOptionsItemSelected(item);
}
public void findAndRemoveFragment() {
FragmentManager mgr = getFragmentManager();
DetailFragment frag =
(DetailFragment) mgr.findFragmentByTag(DetailFragment.TAG);
if (frag == null) {
// No fragment found, possibly because the transaction
// hasn't completed yet.
} else {
// Fragment found. You can use it here.
FragmentTransaction trans = mgr.beginTransaction();
trans.remove(frag);
trans.commit();
// When the main thread runs, the fragment will be
// removed from the activity.
}
}
public void deviceStorage() {
// Read in a private file
try {
FileInputStream fis = this.openFileInput("some_file.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// Create new or open existing private file
try {
FileOutputStream fos = this.openFileOutput("some_other_file.txt", Context.MODE_PRIVATE);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
private void writeToFile(Context _c, String _filename, String _data) {
File external = _c.getExternalFilesDir(null);
File file = new File(external, _filename);
try {
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
if(myObject == null) {
myObject = new SerialCustomObject();
}
myObject.setData(_data);
oos.writeObject(myObject);
oos.close();
// Write bytes to the stream
fos.write(_data.getBytes());
// Close the stream to save the file.
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private String readFromFile(String _filename) {
File external = getExternalFilesDir(null);
File file = new File(external, _filename);
try {
FileInputStream fin = new FileInputStream(file);
InputStreamReader inReader = new InputStreamReader(fin);
BufferedReader reader = new BufferedReader(inReader);
// Reading data from our file using the reader
// and storing it our string buffer.
StringBuffer buffer = new StringBuffer();
String text = null;
// Make sure a line of text is available to be read.
while((text = reader.readLine()) != null) {
buffer.append(text + "\n");
}
// Close the reader and underlying stream.
reader.close();
// Convert the buffer to a string.
return buffer.toString();
} catch(IOException e) {
e.printStackTrace();
}
return null;
}
#Override
public void displayText(String myText) {
DetailFragment frag = (DetailFragment) getFragmentManager().findFragmentByTag(DetailFragment.TAG);
if (frag == null){
frag = DetailFragment.newInstance(myText);
getFragmentManager().beginTransaction()
.replace(R.id.container2,frag,DetailFragment.TAG)
.commit();
}else {
frag.setDisplayInfo(myText);
}
}
//#Override
public void onClick(View _v){
myEdit = (EditText)findViewById(R.id.myEditText);
String newString = myEdit.getText().toString();
Log.v(Tag,newString);
}
// the method for when the button is clicked
public void myClick(View _v){
// create a string to grab the text of the edit text
String myString = myEdit.getText().toString();
// replace the spaces with + to encode into the url
String encodedString = myString.replace(" ","+");
//check to see if online and if so continue to get the JSON data if not toast a message telling the user no connection
if (isOnline()){
requestData("https://maps.googleapis.com/maps/api/place/textsearch/json?query="+encodedString+"&key=AIzaSyB9iOw6wF4FwbOdUTZYiU_MxsbfWM5iMOI");
}else Toast.makeText(this, "Network isn't available", Toast.LENGTH_SHORT).show();
}
// method to get the data from ASYNC task
private void requestData(String uri) {
MyTask task = new MyTask();
task.execute(uri);
}
// method to check internet connectivity
protected boolean isOnline(){
ConnectivityManager cm =(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnectedOrConnecting();
}
protected void updateDisplay(ArrayList<Places> placeList){
// get instance of the Master List fragment then replaces container1 and commits it to the activity
MasterFragment frag = MasterFragment.newInstance(placeList);
getFragmentManager().beginTransaction()
.replace(R.id.container1, frag, MasterFragment.TAG).commit();
}
// Async task method to do network action in
private class MyTask extends AsyncTask<String ,String ,String>{
#Override
protected void onPreExecute() {
// add this to the task
tasks.add(this);
}
#Override
protected String doInBackground(String... params) {
return HttpManager.getData(params[0]);
}
#Override
protected void onPostExecute(String result) {
tasks.remove(this);
if(null != result && !result.isEmpty()) {
placeList = JSONParser.parseFeed(result);
updateDisplay(placeList);
}else {
Toast.makeText(MainActivity.this, "Can't connect to API", Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onProgressUpdate(String... values) {
}
}
}
DetailFragment.java
package com.brianstacks.project1.fragments;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.brianstacks.project1.R;
/**
* Created by Brian Stacks
* on 10/27/14
* for FullSail.edu.
*/
public class DetailFragment extends Fragment {
public static final String TAG = "DetailFragment.TAG";
public static final String ARG_TAG = "DetailFragment.TAG";
public static DetailFragment newInstance(String myString) {
DetailFragment frag = new DetailFragment();
Bundle args = new Bundle();
args.putString(ARG_TAG, myString);
frag.setArguments(args);
return frag;
}
#Override
public View onCreateView(LayoutInflater _inflater, ViewGroup _container,
Bundle _savedInstanceState) {
// Create and return view for this fragment.
return _inflater.inflate(R.layout.detail_layout, _container, false);
}
#Override
public void onActivityCreated(Bundle _savedInstanceState) {
super.onActivityCreated(_savedInstanceState);
Bundle args = getArguments();
if(args != null && args.containsKey(ARG_TAG)){
setDisplayInfo(args.getString(ARG_TAG));
}
}
public void setDisplayInfo(String myText){
getArguments().putString(ARG_TAG,myText);
// Get our TextView and set some text to it.
TextView tv;
tv = (TextView)getView().findViewById(R.id.detailText);
tv.setText(myText);
}
}
MasterFragment.java
package com.brianstacks.project1.fragments;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListFragment;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import com.brianstacks.project1.JSONParser;
import com.brianstacks.project1.MainActivity;
import com.brianstacks.project1.Places;
import com.brianstacks.project1.PlacesAdapter;
import com.brianstacks.project1.R;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Brian Stacks
* on 10/27/14
* for FullSail.edu.
*/
public class MasterFragment extends ListFragment{
public static final String TAG = "MasterFragment.TAG";
public static final String KEY = "places";
private OnListItemClickListener mListener;
private ArrayList<Places> placeList2;
public static MasterFragment newInstance(ArrayList<Places> placeList) {
MasterFragment masterFragment = new MasterFragment();
Bundle args = new Bundle();
args.putSerializable("places", placeList);
masterFragment.setArguments(args);
return masterFragment;
}
public interface OnListItemClickListener{
public void displayText(String myText);
}
#Override
public void onAttach(Activity activity){
super.onAttach(activity);
if (activity instanceof OnListItemClickListener){
mListener = (OnListItemClickListener) activity;
}else {
throw new IllegalArgumentException("Containing Activity must implement the OnListItemClicked");
}
}
#Override
public void onActivityCreated(Bundle _savedInstanceState) {
super.onActivityCreated(_savedInstanceState);
if (_savedInstanceState == null){
Bundle args = getArguments();
String myStrings=args.getString("places");
Log.v("Places",myStrings);
/*String[] presidents = getResources().getStringArray(R.array.presidents);
//ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, presidents);
//PlacesAdapter adapter2 = new PlacesAdapter(this.getActivity(),R.layout.item_place,placeList);
//setListAdapter(adapter2);
}
#Override
public void onListItemClick(ListView _l, View _v, int _position, long _id) {
String president = (String)_l.getItemAtPosition(_position);
mListener.displayText(president);
*/
}
}
}
HTTPManager.java
package com.brianstacks.project1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* Created by Brian Stacks
* on 10/20/14
* for FullSail.edu.
*/
public class HttpManager {
public static String getData(String uri){
BufferedReader reader = null;
try {
URL url = new URL(uri);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
StringBuilder sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
while ((line = reader.readLine()) != null){
sb.append(line).append("");
}
return sb.toString();
}catch (Exception e){
e.printStackTrace();
return null;
}finally {
if (reader!=null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
JSONParser.java
package com.brianstacks.project1;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Brian Stacks
* on 10/20/14
* for FullSail.edu.
*/
public class JSONParser {
public static ArrayList<Places> parseFeed(String content) {
JSONObject myObj;
try {
myObj = new JSONObject(content);
JSONArray result = myObj.getJSONArray("results");
ArrayList<Places> placeList = new ArrayList<>();
for (int i = 0; i < result.length(); i++) {
JSONObject obj = result.getJSONObject(i);
Places place = new Places();
place.setName(obj.getString("name"));
place.setFormatted_address(obj.getString("formatted_address"));
place.setTypes(obj.getString("types"));
//place.setPhotos(obj.getString("photos"));
placeList.add(place);
}
return placeList;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
}
Places.java
import java.io.Serializable;
/**
* Created by Brian Stacks
* on 10/22/14
* for FullSail.edu.
*/
public class Places implements Serializable {
private String pName;
private String pTypes;
private String pFormatted_address;
public Places(){
pName ="";
pTypes ="";
pFormatted_address = "";
}
public String getName() {
return pName;
}
public void setName(String name) {
pName = name;
}
public String getTypes() {
return pTypes;
}
public void setTypes(String types) {
pTypes= types;
}
public String getFormatted_address() {
return pFormatted_address;
}
public void setFormatted_address(String formatted_address) {
pFormatted_address=formatted_address;
}
}
Any help is much appreciated
ALSO was reading this post but to no avail LINK!
I found my solution to this problem, it was I was trying to cast my Objectin my MasterFragment.java as a String when the code was expecting an ArrayList<Places> changed that bit of code and pow there it was, no error.
Old Code
Bundle args = getArguments();
String myStrings=args.getString("places");
New Code
Bundle args = getArguments();
ArrayList myStrings = args.getParcelableArrayList("places");