I have a Fragment with AsyncTask inside an Activity. But i get this exception when i run the search:
Attempt to invoke virtual method 'android.content.res.Resources$Theme android.content.Context.getTheme()' on a null object reference.
It has something to do with the Fragment not knowing if the Activity is running, but i don't know how to fix it.
Please help.
Here is the code:
class Send_API extends AsyncTask<String, Void, String> {
private ProgressDialog dialog;
#Override
protected void onPreExecute() {
if (movieList != null){
movieList.clear();
adapter.notifyDataSetChanged();
}
dialog = new ProgressDialog(getActivity());
dialog.setMessage("Searching...");
dialog.show();
}
#Override
protected String doInBackground(String... params) {
String queryString = null;
try {
queryString = "" +
"s=" + URLEncoder.encode(txt, "utf-8");
} catch (UnsupportedEncodingException e) {
}
return HttpHandler.get(params[0], queryString);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
dialog.dismiss();
if (result == null) {
Toast.makeText(getActivity(), "error getting results...", Toast.LENGTH_LONG).show();
} else {
try {
JSONObject json = new JSONObject(result);
JSONArray searchArray = json.getJSONArray("Search");
for (int i = 0; i < searchArray.length(); i++) {
JSONObject searchObject = searchArray.getJSONObject(i);
String title = searchObject.getString("Title");
String type = searchObject.getString("Type");
String year = searchObject.getString("Year");
String imdbID = searchObject.getString("imdbID");
String poster_url = searchObject.getString("Poster");
movieList.add(new Movie(title, type, year, imdbID, poster_url));
Log.e(TAG, "MovieList is " + movieList);
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getActivity(), "error parsing results...", Toast.LENGTH_LONG).show();
}
adapter.notifyDataSetChanged();
}
}
}
dialog = new ProgressDialog(getActivity());
getActivity() will return null when you're initializing your Fragment. You'll have to wait until onAttach() in the fragment lifecycle for it to return non-null.
That's the reason for the NPE.
Overall, don't have non-default constructors in fragments. Set up the fragment view only in onCreateView().
Try to pass base context to your asynctask and replace getActivity() with it or getApplicationContext()
Related
I've got my main startup class loading MainActivity but I'm trying to figure out how to access the TextView from another class which is loading information from a database. I would like to publish that information to the TextView.
private class DateValidation extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
//Showing progress dialog
}
#Override
protected String doInBackground(String... arg0) {
String hallId = arg0[0];
String date = arg0[1];
String link;
String data;
BufferedReader bufferedReader;
String result;
try {
data = "?id=" + URLEncoder.encode(hallId, "UTF-8");
data += "&date=" + URLEncoder.encode(date, "UTF-8");
link = "https://www.adoetech.co.tz/ehall/frontend/index.php/hall/validate-date" + data;
URL url = new URL(link);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
result = bufferedReader.readLine();
Log.d("postData: ", link);
return result;
} catch (Exception e) {
return "Exception: " + e.getMessage();
}
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
try {
JSONObject jsonObj = new JSONObject(result);
boolean query_result = jsonObj.getBoolean("success");
String response = jsonObj.getString("data");
if (query_result) {
Toast.makeText(HallsDetails.this, response, Toast.LENGTH_LONG).show();
} else if (!query_result) {
Log.d("onPostExecute: ", "free");
Toast.makeText(HallsDetails.this, response, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(HallsDetails.this, response, Toast.LENGTH_SHORT).show();
//JSONArray dateVal = jsonObj.getJSONArray("data");
I need to setTest from here and I have declear hallPrice from MainActivity help Please
hallPrice.setText("300000000");
}
} catch (JSONException e) {
e.printStackTrace();
Log.e("onPostExecute: ", String.valueOf(result));
Toast.makeText(HallsDetails.this, "Error parsing JSON data.", Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(HallsDetails.this, "Couldn't get any JSON data.", Toast.LENGTH_SHORT).show();
}
}
}
Use intent to pass data from one activity to another like this:-
Intent in = new Intent(MainActivity.this, DateValidation.class);
in.putExtra("key", "300000000");
startActivity(in);
And in your DateValidation Activity do:-
Intent i = getIntent();
String value = i.getStringExtra("key");
hallPrice.setText(value);
You can pass the TextView in your AsyncTask.
public class DateValidation extends AsyncTask<String,String,String> {
TextView mTextView;
public DateValidation (TextView textView){
mTextView = textView;
}
#Override
protected String doInBackground(String... strings) {
/**
* do process here
*/
return "Result String here";
}
#Override
protected void onPostExecute(String result) {
mTextView.setText(result);
}
}
I am trying to develop an application that reads jokes from a URL. I am using an AsyncTask to read from URL and then put the string to a textView. But I can't figure out why it isn't working.
Here is my code:
public class MainActivity extends AppCompatActivity {
private Button oneJokeBtn, threeJokesBtn;
private final static String ERROR_TAG = "Download Error";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Capturing our buttons from the view
oneJokeBtn = findViewById(R.id.joke_1);
threeJokesBtn = findViewById(R.id.joke_3);
// Register the onClick listener
oneJokeBtn.setOnClickListener(buttonHandler);
threeJokesBtn.setOnClickListener(buttonHandler);
// Declaring the Spinner
Spinner spinner = findViewById(R.id.spinner);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.length_array, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter);
// Spinner onItemSelector implemented in the OnCreate Method
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (position){
case 0:
Toast.makeText(parent.getContext(), R.string.short_toast, Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(parent.getContext(), R.string.medium_toast, Toast.LENGTH_SHORT).show();
break;
case 2:
Toast.makeText(parent.getContext(), R.string.long_toast, Toast.LENGTH_SHORT).show();
break;
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
/** AsyncTask that reads one joke directly from the URL and adds it to the textView */
private class Download1JokeAsyncTask extends AsyncTask <Void, Void, String> {
private ProgressDialog progressDialog;
private String mResponse = "";
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage(getString(R.string.progress_msg));
progressDialog.setIndeterminate(true);
progressDialog.show();
}
#Override
protected String doInBackground(Void... voids) {
String joke = null;
try {
// Open a connection to the web service
URL url = new URL( "http://www-staff.it.uts.edu.au/~rheise/sarcastic.cgi" );
URLConnection conn = url.openConnection();
// Obtain the input stream
BufferedReader in = new BufferedReader( new InputStreamReader(conn.getInputStream()));
// The joke is a one liner, so just read one line.
joke = in.readLine();
// Close the connection
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
Log.e(ERROR_TAG, "Exception: ", e);
mResponse = getString(R.string.fail_msg);
} catch (IOException e) {
e.printStackTrace();
Log.e(ERROR_TAG, "Exception: ", e);
mResponse = getString(R.string.fail_msg);
}
return joke;
}
#Override
protected void onPostExecute(String joke) {
TextView tv = findViewById(R.id.tv_joke);
if (joke == null) {
tv.setText(R.string.fail_msg);
}
else {
tv.setText(joke);
}
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
}
/** AsyncTask that reads three jokes directly from the URL and adds it to the textView */
private class Download3JokeAsyncTask extends AsyncTask<Void, Integer, String[]> {
private ProgressDialog mProgressDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setProgress(0);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setCancelable(true);
mProgressDialog.setMessage(getString(R.string.three_jokes_btn));
mProgressDialog.show();
}
#Override
protected String[] doInBackground(Void... voids) {
int count = 2;
for (int i = 0; i < 2; i++){
try {
URL url = new URL("http://www.oracle.com/");
URLConnection conn = url.openConnection();
// Obtain the input stream
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
// The joke is a one liner, so just read one line.
String joke;
while ((joke = in.readLine()) != null) {
System.out.println(joke);
}
// Close the connection
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
Log.e(ERROR_TAG, "Exception: ", e);
} catch (IOException e) {
e.printStackTrace();
Log.e(ERROR_TAG, "Exception: ", e);
}
publishProgress((int) ((i / (float) count) * 100));
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
setProgress(0);
}
#Override
protected void onPostExecute(String[] strings) {
super.onPostExecute(strings);
}
}
/** onClickListener that gets the id of the button pressed and download jokes accordingly */
OnClickListener buttonHandler = new OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.joke_1:
new Download1JokeAsyncTask().execute();
break;
case R.id.joke_3:
new Download3JokeAsyncTask().execute();
break;
}
}
};
The AsyncTask is called Download1JokeAsyncTask, it is supposed to read from URL and then put it into a text view. and I've put an error message to appear in the text view if the joke (the string where the joke is stored) is null.
And always the text view says that it failed to download a message.
Please help.
I went to your joke page and inspecting the source (in Firefox) and I found this:
<html>
<head>
<link rel="alternate stylesheet" type="text/css" href="resource://content-accessible/plaintext.css" title="Wrap Long Lines">
</head>
<body>
<pre>I'm really good at stuff until people watch me do that stuff.</pre>
</body>
</html>
So you could save the whole output as a String and then use this:
string.substring(string.indexOf("<pre>"), string.indexOf("</pre>");
string.substring(4);
Basically you are downloading only the first line of the page which would be the content declaration.
Instead you need to download the sixth line and remove the pre tags.
Good Luck!
I've done a search on another stackoverflow post for 2 hours but still can not solve this problem. I have a variable called copyAudioListIqro with List String datatype in DetailMemilihIqro Activity class. When the variable called audioIqros in the AsyncTask class (precisely in the onPostExecute method) this list has a value from my json and I want to copy audioIqros variable to copyAudioListIqro via updateData method (outside the asynctask class). When I see the log monitor on updateData method I can see the value from copyAudioListIqro, but the problem is, when I access it via readDataAudioURL method(outside the asynctask class) copyAudioListIqro variable becomes null.
What is the solution for this problem?
Thank you
Here is the overall DetailMemilihIqro class
public class DetailMemilhIqro extends AppCompatActivity {
private ProgressDialog pDialog;
private List<ModelAudioIqro> audioIqros;
private List<String> copyAudioListIqro;
private AudioAdapter mAdapter;
private RecyclerView recyclerView;
private String TAG = DetailMemilihIqro.class.getSimpleName();
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail_memilih_iqro);
recyclerView = (RecyclerView) findViewById(R.id.rvCVAudioIqro);
pDialog = new ProgressDialog(this);
audioIqros = new ArrayList<>();
mAdapter = new AudioAdapter(getApplicationContext(), audioIqros);
context = getApplicationContext();
copyAudioListIqro = new ArrayList<>();
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
Bundle getPosition = getIntent().getExtras();
int position = getPosition.getInt("positionUserClicked");
Log.d(TAG, "Position User clicked " + position);
if (position == 0) {
String endpoint = "http://latihcoding.com/jsonfile/audioiqro1.json";
new DownloadTask().execute(endpoint);
} else if (position == 1) {
String endpoint = "http://latihcoding.com/jsonfile/audioiqro2.json";
new DownloadTask().execute(endpoint);
} else if (position == 2) {
String endpoint = "http://latihcoding.com/jsonfile/audioiqro3.json";
new DownloadTask().execute(endpoint);
}
readDataAudioURL();
}
public void updateData(List<String> pathUrl) {
for (int i = 0; i < pathUrl.size(); i++) copyAudioListIqro.add(pathUrl.get(i));
Log.d(TAG, "updateData Method " + copyAudioListIqro.toString());
}
public void readDataAudioURL() {
Log.d(TAG, "readDataAudioURL Method " + copyAudioListIqro.toString());
}
public class DownloadTask extends AsyncTask<String, Void, List<String>> {
List<String> modelAudioIqroList;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog.setMessage("Downloading json...");
pDialog.show();
}
#Override
protected List<String> doInBackground(String... strings) {
modelAudioIqroList = new ArrayList<>();
int result;
HttpURLConnection urlConnection;
try {
URL url = new URL(strings[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
// 200 represents HTTP OK
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
parseResult(response.toString());
result = 1; // Successful
Log.d(TAG, "Result " + result);
} else {
//"Failed to fetch data!";
result = 0;
Log.d(TAG, "Result " + result);
}
} catch (Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
return modelAudioIqroList; //"Failed to fetch data!";
}
#Override
protected void onPostExecute(List<String> audioIqros) {
super.onPostExecute(audioIqros);
pDialog.hide();
if (!audioIqros.isEmpty()) {
updateData(modelAudioIqroList);
} else {
Toast.makeText(context, "Empty", Toast.LENGTH_SHORT).show();
}
}
private void parseResult(String result) {
try {
JSONArray response = new JSONArray(result);
for (int i = 0; i < response.length(); i++) {
JSONObject object = response.getJSONObject(i);
ModelAudioIqro modelAudioIqro = new ModelAudioIqro();
modelAudioIqro.setName(object.getString("name"));
modelAudioIqro.setUrl(object.getString("url"));
String path = modelAudioIqro.getUrl();
Log.d(TAG, "String path " + path);
modelAudioIqroList.add(path);
}
} catch (JSONException e) {
e.printStackTrace();
}
mAdapter.notifyDataSetChanged();
}
}
}
Log for the copyAudioListIqro in the updateDataMethod
Log for the copyAudioListIqro in the readDataAudioURL
readDataAudioURL() call, that is a plain Log call, should be moved. Infact the task is asynch by nature, so oblivously the variable copyAudioListIqro won't have been initialized right after the task's start (.execute() method).
You're doing right, anyway, in notyfiying dataset change to list...You should just move it to postExecute as well...
I suggest to move all "after network" code to that postExecute, so that UI can be updated asynchronously ONLY when data is available and without blocking main thread. You can 'read' variables in the inner class, so just declare them final:
#Override
protected void onPostExecute(List<String> audioIqros) {
super.onPostExecute(audioIqros);
pDialog.hide();
if (!audioIqros.isEmpty()) {
updateData(modelAudioIqroList);
//data is now updated, notify datasets and/or send broadcast
mAdapter.notifyDataSetChanged();
readDataAudioURL();
} else {
Toast.makeText(context, "Empty", Toast.LENGTH_SHORT).show();
}
}
A more elaborate pattern would include broadcast receiver and intents, but I guess this is out of this question's scope.
I'm getting errors when i'm trying to parse the datas.
The program is to retrieve the datas from database and parse it to the main menu where the RecycleView lists out the datas such as name,username,image and description.
I'm following this tutorial https://www.youtube.com/watch?v=g30Q9KHubTU
This is the code with errors.
DataParser.java
public class DataParser extends AsyncTask<Void,Void,Boolean> { //<<<line 22
Context c;
String jsonData;
RecyclerView rv;
ProgressDialog pd;
ArrayList<Item> items = new ArrayList<>();
public DataParser(Context c, String jsonData, RecyclerView rv) {
this.c = c;
this.jsonData = jsonData;
this.rv = rv;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(c);
pd.setTitle("Parse");
pd.setMessage("Parsing...Please wait.");
pd.show();
}
#Override
protected Boolean doInBackground(Void... params) {
return null;
}
#Override
protected void onPostExecute(Boolean success) {
super.onPostExecute(success);
pd.dismiss();
if(success) //<<<line 59
{
//bind
MyAdapter adapter = new MyAdapter(c,items);
rv.setAdapter(adapter);
}
else
{
Toast.makeText(c, "Unable to parse", Toast.LENGTH_SHORT).show();
}
}
private Boolean parseData()
{
try
{
JSONArray ja = new JSONArray(jsonData);
JSONObject jo;
items.clear();
Item item;
for(int i = 0; i<ja.length();i++)
{
jo=ja.getJSONObject(i);
int itemid = jo.getInt("itemid");
String imagepath = jo.getString("imagepath");
String itemname = jo.getString("itemname");
String username = jo.getString("username");
String itemdesc = jo.getString("itemdesc");
item = new Item();
item.setId(itemid);
item.setItemname(itemname);
item.setUsername(username);
item.setItemdesc(itemdesc);
item.setImagepath(imagepath);
items.add(item);
}
return true;
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
}
These are the errors
java.lang.NullPointerException:
Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference
at chengweifeng1132701116.fyp.m_MySQL.DataParser.onPostExecute(DataParser.java:59)
at chengweifeng1132701116.fyp.m_MySQL.DataParser.onPostExecute(DataParser.java:22)
This is because you are always returning null from doInBackground. So, your success variable is always null in onPostExecute(). Have the appropriate logic for parsing inside doInBackground and based on whether it was successful or not, return true or false.
I'm using URLEncoder in my activity. but i have a error in MyTask. I have marked the error with Error in my code.
public class Search_Ringtone extends SherlockActivity{
ListView lsv_latest;
List<ItemRingCategoryItem> arrayOfRingcatItem;
RingCateItemAdapter objAdapterringitemitem;
AlertDialogManager alert = new AlertDialogManager();
private ItemRingCategoryItem objAllBean;
JsonUtils util;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.ringcatitem_activity);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setIcon(new ColorDrawable(getResources().getColor(android.R.color.transparent)));
lsv_latest=(ListView)findViewById(R.id.latest_list);
arrayOfRingcatItem=new ArrayList<ItemRingCategoryItem>();
if (JsonUtils.isNetworkAvailable(Search_Ringtone.this)) {
String str = Constant.SEARCH_RINGTONE_URL+Constant.SEARCH.replace(" ", "%20");
String myUrl = URLEncoder.encode(str, "UTF-8");
MyTask().execute(myUrl); //*Error*
} else {
showToast("No Network Connection!!!");
alert.showAlertDialog(Search_Ringtone.this, "Internet Connection Error",
"Please connect to working Internet connection", false);
}
lsv_latest.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
// TODO Auto-generated method stub
objAllBean=arrayOfRingcatItem.get(position);
Intent intplay=new Intent(getApplicationContext(),SingleRingtone.class);
Constant.RINGTONE_ITEMID=objAllBean.getRingItemId();
startActivity(intplay);
}
});
}
private class MyTask extends AsyncTask<String, Void, String> {
ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Search_Ringtone.this);
pDialog.setMessage("لطفا صبر کنید...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... params) {
return JsonUtils.getJSONString(params[0]);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (null != pDialog && pDialog.isShowing()) {
pDialog.dismiss();
}
if (null == result || result.length() == 0) {
showToast("Server Connection Error");
alert.showAlertDialog(getApplicationContext(), "Server Connection Error",
"May Server Under Maintaines Or Low Network", false);
} else {
try {
JSONObject mainJson = new JSONObject(result);
JSONArray jsonArray = mainJson.getJSONArray(Constant.LATEST_ARRAY_NAME);
JSONObject objJson = null;
if(jsonArray.length()==0)
{
showToast("موردی پیدا نشد!");
}
else
{
for (int i = 0; i < jsonArray.length(); i++) {
objJson = jsonArray.getJSONObject(i);
ItemRingCategoryItem objItem = new ItemRingCategoryItem();
objItem.setRingItemId(objJson.getString(Constant.CATEITEMRING_RINDID));
objItem.setRingItemCatId(objJson.getString(Constant.CATEITEMRING_RINDCATID));
objItem.setRingItemCatName(objJson.getString(Constant.CATEITEMRING_CATENAME));
objItem.setRingItemName(objJson.getString(Constant.CATEITEMRING_RINGNAME));
objItem.setRingItemUrl(objJson.getString(Constant.CATEITEMRING_RINDURL));
objItem.setRingItemDownCount(objJson.getString(Constant.CATEITEMRING_RINDDOWNCOUNT));
objItem.setRingItemUser(objJson.getString(Constant.CATEITEMRING_RINDUSER));
objItem.setRingItemTag(objJson.getString(Constant.CATEITEMRING_RINDTAG));
objItem.setRingItemSize(objJson.getString(Constant.CATEITEMRING_RINDSIZE));
objItem.setRingStar(objJson.getString(Constant.LATESTRING_RINGSTAR));
objItem.setRingImage(objJson.getString(Constant.LATESTRING_RINGIMAGE));
arrayOfRingcatItem.add(objItem);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
setAdapterToListview();
}
}
}
Shouldn't it be new MyTask().execute(myURL);?
Also because it's an AsyncTask you need to retain a reference to it until it's finished or else the garbage collector destroys it.
i write like this and solved thank you everyone:
if (JsonUtils.isNetworkAvailable(Search_Ringtone.this)) {
String str = Constant.SEARCH_RINGTONE_URL+Constant.SEARCH.replace(" ", "%20");
String myUrl = null;
try {
myUrl = URLEncoder.encode(str, "UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new MyTask().execute(myUrl);