Android crash in AsyncTask - java

When I run my projent and it's run AsyncTask from the activity that shows all content of the item the APP crash showing the follow error message:
06-17 20:56:52.856 418-428/? E/art﹕ Failed sending reply to debugger: Broken pipe
06-17 20:57:07.391 418-767/com.example.user.project_test E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #3
Process: com.example.user.project_test, PID: 418
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6357)
at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:909)
at android.view.ViewGroup.invalidateChild(ViewGroup.java:4690)
at android.view.View.invalidateInternal(View.java:11801)
at android.view.View.invalidate(View.java:11765)
at android.view.View.invalidate(View.java:11749)
at android.widget.TextView.checkForRelayout(TextView.java:6858)
at android.widget.TextView.setText(TextView.java:4057)
at android.widget.TextView.setText(TextView.java:3915)
at android.widget.TextView.setText(TextView.java:3890)
at com.example.user.project.itemActivity$getitem.doInBackground(itemActivity.java:132)
at com.example.user.project.itemActivity$getitem.doInBackground(itemActivity.java:84)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
06-17 20:57:07.612 418-418/com.example.user.project_test E/WindowManager﹕ android.view.WindowLeaked: Activity com.example.user.project.itemActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{19feb64d V.E..... R......D 0,0-1026,348} that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:363)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:271)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:85)
at android.app.Dialog.show(Dialog.java:298)
at com.example.user.project.itemActivity$getitem.onPreExecute(itemActivity.java:96)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:591)
at android.os.AsyncTask.execute(AsyncTask.java:539)
at com.example.user.project.itemActivity.onCreate(itemActivity.java:71)
at android.app.Activity.performCreate(Activity.java:5990)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1106)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2387)
at android.app.ActivityThread.access$800(ActivityThread.java:151)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.description.invoke(Native description)
at java.lang.reflect.description.invoke(description.java:372)
at com.android.internal.os.ZygoteInit$descriptionAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
I put here my current code
ItemActivity.java (it's the class that crash in AsyncTask:
public class ItemActivity extends AppCompatActivity {
private static final String TAG_SUCCESS = "success";
private static final String TAG_ITEM = "item";
private static final String TAG_ITEM_NAME = "name";
private static final String TAG_ITEM_description = "item";
Integer item_id;
String name;
String username;
String item;
TextView itemname;
TextView itemitem;
ProgressDialog pDialog;
JSONParser jParser;
RecyclerView recycler;
ActionBar actionBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item);
Intent i = getIntent();
if (i.hasExtra("item_id")) {
Bundle bd = getIntent().getExtras();
/*if ((!bd.getString("name").equals(null) || bd.getString("name").trim().length() > 0) && (!bd.getString("username").equals(null) || bd.getString("username").trim().length() > 0) && (!bd.getString("description").equals(null) || bd.getString("description").trim().length() > 0)) {
name = bd.getString("name");
username = bd.getString("username");
description = bd.getString("description");
}*/
item_id = bd.getInt("item_id");
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
actionBar = getSupportActionBar();
actionBar.setTitle(R.string.app_name);
itemname = (TextView) findViewById(R.id.itemName);
itemdescription = (TextView) findViewById(R.id.itemDescription);
new getitem().execute();
/*recycler = (RecyclerView) findViewById(R.id.recycler);
recycler.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recycler.setLayoutManager(layoutManager);*/
}
/**
* Background Async Task to Get complete item details
*/
class getitem extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
*/
#Override
protected void onPreExecute() {
super.onPreExecute();
if (pDialog != null) {
pDialog = null;
}
pDialog = new ProgressDialog(itemActivity.this);
pDialog.setMessage(getResources().getString(R.string.loadingitem));
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* Getting item details in background thread
*/
protected String doInBackground(String... params) {
// updating UI from Background Thread
// Check for success tag
int success;
try {
// Building Parameters
List<NameValuePair> myParameters = new ArrayList<NameValuePair>();
myParameters.add(new BasicNameValuePair("item_id", Integer.toString(item_id)));
// getting item details by making HTTP request
// Note that item details url will use GET request
jParser = new JSONParser();
JSONObject json = jParser.makeHttpRequest(AppConfig.URL_GET_item, "GET", myParameters);
// check your log for json response
Log.d("Single item Details", json.toString());
// json success tag
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// successfully received item details
JSONArray itemObj = json.getJSONArray(TAG_item); // JSON Array
// get first item object from JSON Array
JSONObject item = itemObj.getJSONObject(0);
// item with this pid found
// Edit Text
itemname.setText(item.getString(TAG_item_NAME));
itemdescription.setText(item.getString(TAG_item_description));
} else {
// item with pid not found
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* *
*/
protected void onPostExecute(String file_url) {
// dismiss the dialog once got all details
pDialog.dismiss();
}
}
/*itemname=(TextView)
findViewById(R.id.itemName);
itemdescription=(TextView)
findViewById(R.id.itemdescription);*/
//itemname.setText(name);
//itemdescription.setText(description);
}
activity_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/navigation_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="#bool/fitsSystemWindows">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="#dimen/status_bar_height"
android:background="?colorPrimary" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="#dimen/status_bar_height"
android:background="?colorPrimaryDark" />
</LinearLayout>
<FrameLayout
android:id="#+id/flma"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/status_bar_height">
<TextView
android:id="#+id/itemName"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top"
android:layout_marginTop="80dp"
android:gravity="center"
android:textAllCaps="true"
android:textSize="25dp"
android:textStyle="bold" />
<ImageView
android:id="#+id/itemPhoto"
android:layout_width="fill_parent"
android:layout_height="300dp"
android:layout_gravity="center"
android:background="#000"
android:src="#drawable/header" />
<TextView
android:id="#+id/itemdescription"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="50dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
</FrameLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="#bool/fitsSystemWindows"
app:headerLayout="#layout/navigation_drawer_header"
app:menu="#menu/navigation_drawer_menu"
app:theme="#style/NavigationViewTheme" />
</android.support.v4.widget.DrawerLayout>
I'm searching and I found that checking if progress dialog is not null set it null the problem can be fix but doesn't work for me.
Does anyone know if I put something wrong in my class?
Thanks!!
SOLUTION:
Thanks to Itzik Samara and ligi for the help and explanation of the problem, I fix the problem removing the lines indicated by Itzik Samara and adding the following code in onPostExecute:
protected void onPostExecute(String file_url) {
// dismiss the dialog once got all details
try {
itemname.setText(item.getString(TAG_item_NAME));
} catch (JSONException e) {
e.printStackTrace();
}
try {
itemdescription.setText(item.getString(TAG_item_description));
} catch (JSONException e) {
e.printStackTrace();
}
pDialog.dismiss();
}

You cannot touch UI elements in a background thread ( like setText ) You might want to wrap in runOnUIThread() or do that stuff in onPre / onPost execute ( they are on the UI thread ) and read about android threading

your problem are those 2 lines :
itemname.setText(item.getString(TAG_ITEM_NAME));
itemdescription.setText(item.getString(TAG_ITEM_DESCRIPTION));
2 choices :
send the data to onPostExecute and update the EditText from there
use RunOnUiThread and update the 2 EditTexts inside it

Try adding this in your doInBackground()
runOnUiThread(new Runnable() {
#Override
public void run() {
itemname.setText(item.getString(TAG_item_NAME));
itemdescription.setText(item.getString(TAG_item_description));
}
});
Or put this two lines in onPostExecute()
itemname.setText(item.getString(TAG_item_NAME));
itemdescription.setText(item.getString(TAG_item_description));
Here's your entire Class
public class itemActivity extends AppCompatActivity {
private static final String TAG_SUCCESS = "success";
private static final String TAG_item = "item";
private static final String TAG_item_NAME = "name";
private static final String TAG_item_description = "description";
Integer item_id;
String name;
String username;
String description;
TextView itemname;
TextView itemdescription;
ProgressDialog pDialog;
JSONParser jParser;
RecyclerView recycler;
ActionBar actionBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item);
Intent i = getIntent();
if (i.hasExtra("item_id")) {
Bundle bd = getIntent().getExtras();
/*if ((!bd.getString("name").equals(null) || bd.getString("name").trim().length() > 0) && (!bd.getString("username").equals(null) || bd.getString("username").trim().length() > 0) && (!bd.getString("description").equals(null) || bd.getString("description").trim().length() > 0)) {
name = bd.getString("name");
username = bd.getString("username");
description = bd.getString("description");
}*/
item_id = bd.getInt("item_id");
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
actionBar = getSupportActionBar();
actionBar.setTitle(R.string.app_name);
itemname = (TextView) findViewById(R.id.itemName);
itemdescription = (TextView) findViewById(R.id.itemdescription);
new getitem().execute();
/*recycler = (RecyclerView) findViewById(R.id.recycler);
recycler.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recycler.setLayoutManager(layoutManager);*/
}
/**
* Background Async Task to Get complete item details
*/
class getitem extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
*/
#Override
protected void onPreExecute() {
super.onPreExecute();
if (pDialog != null) {
pDialog = null;
}
pDialog = new ProgressDialog(itemActivity.this);
pDialog.setMessage(getResources().getString(R.string.loadingitem));
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* Getting item details in background thread
*/
protected String doInBackground(String... params) {
// updating UI from Background Thread
// Check for success tag
int success;
try {
// Building Parameters
List<NameValuePair> myParameters = new ArrayList<NameValuePair>();
myParameters.add(new BasicNameValuePair("item_id", Integer.toString(item_id)));
// getting item details by making HTTP request
// Note that item details url will use GET request
jParser = new JSONParser();
JSONObject json = jParser.makeHttpRequest(AppConfig.URL_GET_item, "GET", myParameters);
// check your log for json response
Log.d("Single item Details", json.toString());
// json success tag
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// successfully received item details
JSONArray itemObj = json.getJSONArray(TAG_item); // JSON Array
// get first item object from JSON Array
JSONObject item = itemObj.getJSONObject(0);
// item with this pid found
// Edit Text
runOnUiThread(new Runnable() {
#Override
public void run() {
itemname.setText(item.getString(TAG_item_NAME));
itemdescription.setText(item.getString(TAG_item_description));
}
});
} else {
// item with pid not found
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* *
*/
protected void onPostExecute(String file_url) {
// dismiss the dialog once got all details
pDialog.dismiss();
}
}
}

Related

Can not load data to ListView in Activity

I'm using json to load data in Activity class with content following as:
My Activity class:
public class CategoryCarActivity extends ListActivity {
ConnectionDetector cd;
AlertDialogManager alert = new AlertDialogManager();
private ProgressDialog pDialog;
JSONParser jsonParser = new JSONParser();
ArrayList<Category> carsList = new ArrayList<Category>();
JSONArray manufacturers = null;
String manufacturer_id, manufacturer_name;
private static final String URL_MANUFACTURERS = "MyURL";
// ALL JSON node names
private static final String TAG_CARS = "cars";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_MANUFACTURER = "name";
private static final String TAG_PRICE = "price";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category);
cd = new ConnectionDetector(getApplicationContext());
// Check if Internet present
if (!cd.isConnectingToInternet()) {
// Internet Connection is not present
alert.showAlertDialog(CategoryCarActivity.this, "Internet Connection Error",
"Please connect to working Internet connection", false);
// stop executing code by return
return;
}
Intent i = getIntent();
manufacturer_id = i.getStringExtra("id");
carsList = new ArrayList<Category>();
// Loading tracks in Background Thread
new LoadTracks().execute();
// get listview
ListView lv = getListView();
/**
* Listview on item click listener
* SingleTrackActivity will be lauched by passing manufacturer id, car id
* */
lv.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, int arg2, long arg3) {
// On selecting single track get car information
Intent i = new Intent(getApplicationContext(), DetailListCarActivity.class);
// to get car information
// both manufacturer id and car is needed
String manufacturer_id = ((TextView) view.findViewById(R.id.manufacturer_id)).getText().toString();
String car_id = ((TextView) view.findViewById(R.id.car_id)).getText().toString();
Toast.makeText(getApplicationContext(), "Manufacturer Id: " + manufacturer_id + ", Car Id: " + car_id, Toast.LENGTH_SHORT).show();
i.putExtra("manufacturer_id", manufacturer_id);
i.putExtra("car_id", car_id);
startActivity(i);
}
});
}
/**
* Background Async Task to Load all tracks under one album
* */
class LoadTracks extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(CategoryCarActivity.this);
pDialog.setMessage("Loading selected car ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting tracks json and parsing
* */
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// post album id as GET parameter
params.add(new BasicNameValuePair(TAG_ID, manufacturer_id));
// getting JSON string from URL
String json = jsonParser.makeHttpRequest(URL_MANUFACTURERS, "GET",
params);
// Check your log cat for JSON reponse
Log.d("Category List JSON: ", json);
try {
JSONObject jObj = new JSONObject(json);
if (jObj != null) {
String manufacturer_id = jObj.getString(TAG_ID);
manufacturer_name = jObj.getString(TAG_MANUFACTURER);
manufacturers = jObj.getJSONArray(TAG_CARS);
if (manufacturers != null) {
// looping through All cars
for (int i = 0; i < manufacturers.length(); i++) {
JSONObject c = manufacturers.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_ID);
// track no - increment i value
String track_no = String.valueOf(i + 1);
String name = c.getString(TAG_NAME);
String price = c.getString(TAG_PRICE);
// creating new HashMap
// HashMap<String, String> map = new HashMap<String, String>();
Category category = new Category();
category.setManufacturer_id(manufacturer_id);
category.setId(id);
category.setName(name);
category.setPrice(price);
// adding each child node to HashMap key => value
/*
map.put("manufacturer_id", manufacturer_id); // note here
map.put(TAG_ID, car_id);
map.put("track_no", track_no + ".");
map.put(TAG_NAME, name);
map.put(TAG_PRICE, price);
*/
// adding HashList to ArrayList
// carsList.add(map);
carsList.add(category);
}
} else {
Log.d("Manufacturers: ", "null");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String result) {
pDialog.dismiss();
ListAdapter adapter = new ArrayAdapter<Category>(
CategoryCarActivity.this, // the context
R.layout.list_item_categorys, // Simple list item - will toString() your data
carsList // The arraylist
);
// updating listview
setListAdapter(adapter);
}
}
}
list_item_categorys.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/manufacturer_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
<!-- Song id / Hidden by default -->
<TextView
android:id="#+id/car_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone" />
<TextView
android:id="#+id/track_no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="15dip"
android:paddingLeft="5dip"
android:paddingTop="15dip"
android:textColor="#000000"
android:textSize="16dip"
android:layout_alignParentLeft="true"/>
<TextView
android:id="#+id/manufacturer_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="15dip"
android:paddingLeft="5dip"
android:paddingTop="15dip"
android:textColor="#000000"
android:textSize="16dip"
android:layout_toRightOf="#+id/track_no"/>
<TextView
android:id="#+id/price"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:paddingLeft="3dip"
android:paddingRight="6dip"
android:textColor="#9ed321" />
I have debugged and check Logcat and see that data has loaded and everything normal, but don't know why data can not load to ListView
updated
Logcat:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.totoroads.android.app, PID: 4697
java.lang.IllegalStateException: ArrayAdapter requires the resource ID to be a TextView
at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:393)
at android.widget.ArrayAdapter.getView(ArrayAdapter.java:369)
How to fix this problem?? thank you
You're not providing your list to the list view. You need to add your list to your list view with an adapter. This tutorial should help walk you through the process. http://www.vogella.com/tutorials/AndroidListView/article.html
In your postExecute of your asyncTask you can than call adapter.notifyDataSetChanged(). And your view will update with the new list content.
This code looks really similar... maybe copy the rest of it?
You need an Adapter for your data.
protected void onPostExecute(String result) {
// dismiss the dialog after getting all tracks
pDialog.dismiss();
ListAdapter adapter = new ArrayAdapter<Category>(
CategoryCarActivity.this, // the context
android.R.layout.simple_list_item_1, // Simple list item - will toString() your data
carList // The arraylist
);
// updating listview
setListAdapter(adapter);
}
You can also make a subclass of ArrayAdapter<Category> if you really want to customize a layout.
Adding to Ben's answer, you need to set the list to the listview adapter after the asynctask completes its background functionality i.e in onPostExecute() method of the asynctask.
Need to set the list view as suggested by Ben in onPostExecute().
ListView listView = (ListView) findViewById(R.id.your_list_view_id);
listView.getAdapter().notifyDataSetChanged();

Button onClick() does not load the myClickHandlermethod defined in the custom class HttpExampleActivity.java

Code for activity_main.xml:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.example.android.httptry.MainActivity"
android:orientation="vertical">
<EditText
android:id="#+id/myUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/hint"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button"
android:text="#string/button"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:onClick="myClickHandler"
/>
<TextView
android:id="#+id/myText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
</ScrollView>
Code for the HttpExampleActivity.java:
public class HttpExampleActivity extends Activity {
private static final String DEBUG_TAG = "HttpExample";
private EditText urlText;
private TextView textView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
urlText = (EditText) findViewById(R.id.myUrl);
textView = (TextView) findViewById(R.id.myText);
}
// When user clicks button, calls AsyncTask.
public void myClickHandler(View view) {
// Gets the URL from the UI's text field.
String stringUrl = urlText.getText().toString();
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
new DownloadWebpageTask().execute(stringUrl);
} else {
textView.setText("No network connection available.");
}
}
private class DownloadWebpageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
// params comes from the execute() call: params[0] is the url.
try {
return downloadUrl(urls[0]);
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
textView.setText(result);
}
}
private String downloadUrl(String myurl) throws IOException {
InputStream is = null;
// Only display the first 500 characters of the retrieved
// web page content.
int len = 500;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
int response = conn.getResponseCode();
Log.d(DEBUG_TAG, "The response is: " + response);
is = conn.getInputStream();
// Convert the InputStream into a string
String contentAsString = readIt(is, len);
return contentAsString;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} finally {
if (is != null) {
is.close();
}
}
}
// Reads an InputStream and converts it to a String.
public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
Reader reader = null;
reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[len];
reader.read(buffer);
return new String(buffer);
}
}
On checking the logcat, I found the following error message:
Process: com.example.android.httptry, PID: 29936
java.lang.IllegalStateException: Could not find method myClickHandler(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.support.v7.widget.AppCompatButton with id 'button'
I'm fairly new to android development so couldn't understand why despite naming the onClick() method I was getting the above error. Any solutions to resolve this ?
I know this is silly, but it happened to me once, I was missing the android:clickable="true"
Change
tools:context="com.example.android.httptry.MainActivity"
to
tools:context="com.yourpackage.HttpExampleActivity"
or define the myClickHandler method in your com.example.android.httptry.MainActivity class (if there is any such class)
The stack trace that you've shared clearly indicates that
it's looking for a myClickHandler(View) method defined in the context that's given which is com.example.android.httptry.MainActivity in this case but there's no such method defined in that activity.
It's in the HttpExampleActivity.
So, that makes it all clear, either you change the context or define such method in the context class.

Get Variable from another Activity (Android Studio)

I know that there are a lot of answers to this question already, but I'm still having trouble dealing with this concept.
An answer found here shows:
If you didn't want to use a global variable you could always create a method in your activity to return your string.
public String getMyString(){
return item; }
Then in your current activity you could call:
String myValue = LoginScreen.getMyString();
When I try this method, I am returned an error saying "Non-Static method can not be referenced from a static context". However if I make the method static it says that my variable needs to be static, but I need to update the variable. I'll include my code below.
First Activity -
btnSEARCH.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (editTextSearch.getText().toString() != null) {
SearchQueryTerm = editTextSearch.getText().toString();
editTextSearch.setText("");
}
}
});
public String getMyString(){
return SearchQueryTerm;
}
Second Activity-
String SearchQueryTerm = MainActivity.getMyString();
I truly appreciate any help you can give me in this. Thanks so much!! <3
This is my updated code - however it still crashes :(
Activity 1
public void sendMessageIntent(View view) {
Intent search_intent = new Intent(this, SearchActivity.class);
api_intent.putExtra("my_variable", SearchQueryTerm);
startActivity(search_intent);
}
xml file
<Button
android:id="#+id/button_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:text="View"
android:onClick="sendMessageIntent"
/>
Activity 2 -
public String SearchQueryTerm
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_enter_variable);
if (extras != null) {
SearchQueryTerm = extras.getString("my_variable");
}
}
Use putExtra method of an object Intent.
In your first activity create for example :
String value = "value";
Intent i = new Intent(getApplicationContext(), MyActivity.class);
i.putExtra("my_variable",value);
startActivity(i);
In your second activity you can retrieve your variable :
Bundle extras = getIntent().getExtras();
if (extras != null) {
String value = extras.getString("my_variable");
}
It's the best method to pass a variable between activities.
To show you how it works, i have done this code :
XML of first activity :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<EditText
android:id="#+id/editTextSearch"
android:layout_width="200dp"
android:layout_height="wrap_content" />
<Button
android:id="#+id/buttonSearch"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:text="Button"/>
</LinearLayout>
</RelativeLayout>
First Activity :
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnSEARCH = (Button) findViewById(R.id.buttonSearch);
btnSEARCH.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
EditText editTextSearch = (EditText) findViewById(R.id.editTextSearch);
if (editTextSearch.getText().toString() != null) {
String value = "value";
Intent i = new Intent(getApplicationContext(), Main2Activity.class);
i.putExtra("SearchQueryTerm",editTextSearch.getText().toString());
startActivity(i);
editTextSearch.setText("");
}
}
});
}
}
In this first activity we pass the value of the editText in the putExtra method with the key = "SearchQueryTerm".
To retrieve the value of editText do this in your second Activity :
public class Main2Activity extends AppCompatActivity {
String SearchQueryTerm = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Bundle extras = getIntent().getExtras();
if (extras != null) {
SearchQueryTerm = extras.getString("SearchQueryTerm");
}
System.out.println(SearchQueryTerm);
}
}
Now you have the value of your editText in the variable SearchQueryTerm ( Second Activity ).
It works for me, so there is no reason it dont work for you.
Hope it helps.
a good solution is to add a "model" singleton class, where you store data that have to be shared between your activities
example :
public class Model {
private static Model __instance == null;
private Model() {
}
public static Model instance() {
if (__instance == null) {
__instance = new Model();
}
return __instance;
}
private Object mydataToShare = null;
public void setMyDataToShare(Object mydataToShare) {
this.mydataToShare = mydataToShare;
}
public Object getMyDataToShare() {
return mydataToShare;
}
}
to store data :
Model.instance().setMyDataToShare(<value to store>);
to retrieve data :
Object valueToRetrieve = Model.instance().getMyDataToShare();
it allow you to transfer complex data and separate completely logic part from UI

Keeping user logged in with SharedPreferences

I have a Java SessionManager class which contains many methods for different login actions with sharedPreferences (such as creating a login session, clearing login session, etc.). I also have a dispatch activity which is launched when the app is run. This dispatch activity calls a method from my SessionManager class to check if a user is currently logged in. If he/she is, and intent takes them to my main activity. Otherwise, the login activity is called where they can then login, etc. However, whenever I run my app, I get an error. My code for my main activity is as follows:
public class MainList extends AppCompatActivity {
RecyclerView gradeList;
SwipeRefreshLayout swipeRefreshLayout;
public SessionManager session;
static String tab1 = "studentdata";
static String tab2 = "gradebook";
static String tab3 = "weeklysummary";
static String action = "form";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_list);
Log.e("MESSAGE: ", "In second class");
session = new SessionManager(getApplicationContext());
setTheme(R.style.AppTheme);
Toolbar toolbar;
toolbar = (Toolbar)findViewById(R.id.tb);
setSupportActionBar(toolbar);
new infoGetter().execute();
gradeList = (RecyclerView)findViewById(R.id.grade_list);
LinearLayoutManager lm = new LinearLayoutManager(getApplicationContext());
lm.setOrientation(lm.VERTICAL);
gradeList.setLayoutManager(lm);
swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.refresh);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
refreshGrades();
}
});
}
private void refreshGrades(){
new infoGetter().execute();
swipeRefreshLayout.setRefreshing(false);
}
#Override
public void onBackPressed() {
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main_list, 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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public class Wrapper{
public Elements gradeList;
}
private class infoGetter extends AsyncTask<Void, Void, Wrapper> {
String studentID = session.getID();
String username = session.getUser();
String password = session.getPass();
#Override
protected Wrapper doInBackground(Void... params) {
Wrapper w = new Wrapper();
String loginURL = "https://parents.mtsd.k12.nj.us/genesis/parents/j_security_check";
String userDataUrl = "https://parents.mtsd.k12.nj.us/genesis/parents?tab1=" + tab1 + "&tab2=" + tab2 + "&tab3=" + tab3 + "&studentid=" + studentID + "&action=" + action;
Connection.Response response = new GradeFetcher().getRequest(userDataUrl);
Document loggedInDocument = new GradeFetcher().postRequest(loginURL, username, password, studentID, response);
Elements grades = new GradeFetcher().gradeExtractor(loggedInDocument);
w.gradeList = grades;
Log.e("MESSAGE: ","Going to onPostExecute");
return w;
}
protected void onPostExecute(Wrapper w) {
ArrayList<String>gl = new ArrayList<>();
for (Element e:w.gradeList){
gl.add(e.text());
}
String[]gradeData = gl.toArray(new String[gl.size()]);
gradeList = (RecyclerView)findViewById(R.id.grade_list);
LinearLayoutManager lm = new LinearLayoutManager(getApplicationContext());
lm.setOrientation(lm.VERTICAL);
gradeList.setLayoutManager(lm);
gradeList.setAdapter(new RecyclerAdapter(gradeData));
}
}
}
and my error is as follows:
08-06 21:34:19.970 2010-2010/com.aurum.gradebook E/MESSAGE:﹕ In second class
08-06 21:34:20.018 2010-2010/com.aurum.gradebook E/RecyclerView﹕ No adapter attached; skipping layout
08-06 21:34:20.035 2010-2010/com.aurum.gradebook E/RecyclerView﹕ No adapter attached; skipping layout
08-06 21:34:20.182 2010-2038/com.aurum.gradebook E/GET REQUEST﹕ Making GET request to gradebook page
08-06 21:34:20.183 2010-2038/com.aurum.gradebook E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
Process: com.aurum.gradebook, PID: 2010
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.IllegalArgumentException: Data value must not be null
at org.jsoup.helper.Validate.notNull(Validate.java:26)
at org.jsoup.helper.HttpConnection$KeyVal.value(HttpConnection.java:884)
at org.jsoup.helper.HttpConnection$KeyVal.create(HttpConnection.java:864)
at org.jsoup.helper.HttpConnection.data(HttpConnection.java:131)
at com.aurum.gradebook.GradeFetcher.postRequest(GradeFetcher.java:57)
at com.aurum.gradebook.MainList$infoGetter.doInBackground(MainList.java:124)
at com.aurum.gradebook.MainList$infoGetter.doInBackground(MainList.java:109)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            
I have checked through my code multiple times but I cannot find my error. I know it is something to do with my AsycTask my I really don't see where. All help is appreciated and will be rewarded with bounty if possible. I can provide my other code if it is necessary.
My post request:
public Document postRequest(String loginURL, String username, String password, String studentID, Response res) {
Document doc = null;
try {
doc = Jsoup.connect(loginURL)
.userAgent("Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.4 Safari/537.36")
.referrer("https://parents.mtsd.k12.nj.us/genesis/parents?gohome=true")
.cookies(res.cookies())
.data("j_username", username)
.data("j_password", password)
.post();
Log.e("POST REQUEST", "Connecting to login page, posting credentials...");
} catch (IOException ioe) {
ioe.printStackTrace();
}
return doc;
}
I think your username or password is null, please check these values
You can download source code of jsoup at jsoup.org then find that in HttpConnection.java the following code
public KeyVal value(String value) {
Validate.notNull(value, "Data value must not be null");
this.value = value;
return this;
}

How do I make separators for a ListView with a SimpleAdapter

I'm new to the java programming language and I'm trying to build an app. The app has to make a list of worked hours that have been saved in an MySQL database. I found an example app, that helped me retrieving the data from the database and putting it in a ListView.
But now we get to my problem. I want to put separators in the listview.
Now, the date of the worked hours is in every item of the ListView. I want the date only above the first item.
I've searched the internet for a way to do this, but it didn't help me.
This it the code that gets the data and puts it in a ListView:
public class AllUrenActivity extends ListActivity {
String url_all_uren;
String ip;
String proid;
String uid = MainScreenActivity.uid;
String datum;
String datum1;
ImageView btntoevoegen;
// Progress Dialog
private ProgressDialog pDialog;
TextView tvDatum;
// Creating JSON Parser object
JSONParser jParser = new JSONParser();
ArrayList<HashMap<String, String>>urenList;
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_UREN = "uren";
private static final String TAG_TRID = "trid";
private static final String TAG_PROID = "proid";
private static final String TAG_WERKZAAMHEID = "werkzaamheid";
private static final String TAG_TIJD = "tijd";
private static final String TAG_DATUM = "datum";
// products JSONArray
JSONArray uren = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.all_uren);
SharedPreferences settings = getSharedPreferences("databaseIP", 0);
ip = settings.getString("ip", "").toString();
url_all_uren = ("http://"+ip+"/android_connect/get_all_uren.php");
// Hashmap for ListView
urenList = new ArrayList<HashMap<String, String>>();
// Loading products in Background Thread
new LoadAllUren().execute();
// Get listview
ListView lv = getListView();
// on selecting single product
// launching Edit Product Screen
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String proid = ((TextView) view.findViewById(R.id.tvProid)).getText()
.toString();
String werkzaamheid = ((TextView) view.findViewById(R.id.tvWerkzaamheid)).getText()
.toString();
String trid = ((TextView) view.findViewById(R.id.tvTrid)).getText()
.toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(),
AllProjectsActivity.class);
// sending pid to next activity
in.putExtra(TAG_PROID, proid);
in.putExtra(TAG_TRID, trid);
in.putExtra(TAG_WERKZAAMHEID, werkzaamheid);
// starting new activity and expecting some response back
startActivityForResult(in, 100);
}
});
}
// Response from Edit Product Activity
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// if result code 100
if (resultCode == 100) {
// if result code 100 is received
// means user edited/deleted product
// reload this screen again
Intent intent = getIntent();
finish();
startActivity(intent);
}
}
/**
* Background Async Task to Load all product by making HTTP Request
* */
class LoadAllUren extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(AllUrenActivity.this);
pDialog.setMessage("Uren laden...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting All products from url
* */
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("uid", uid));
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_uren, "GET", params);
// Check your log cat for JSON reponse
Log.d("Uren: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
uren = json.getJSONArray(TAG_UREN);
// looping through All Products
for (int i = 0; i < uren.length(); i++) {
JSONObject c = uren.getJSONObject(i);
// Storing each json item in variable
String trid = c.getString(TAG_TRID);
String proid = c.getString(TAG_PROID);
String werkzaamheid = c.getString(TAG_WERKZAAMHEID);
String datum = c.getString(TAG_DATUM);
String tijd = c.getString(TAG_TIJD);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_TRID, trid);
map.put(TAG_WERKZAAMHEID, werkzaamheid);
map.put(TAG_PROID, proid);
map.put(TAG_TIJD, tijd);
map.put(TAG_DATUM, datum);
// adding HashList to ArrayList
urenList.add(map);
}
} else {
// no products found
// Launch Add New product Activity
Intent i = new Intent(getApplicationContext(),
NewProductActivity.class);
// Closing all previous activities
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
AllUrenActivity.this, urenList,
R.layout.list_uren, new String[] { TAG_TRID, TAG_PROID, TAG_WERKZAAMHEID, TAG_TIJD, TAG_DATUM},
new int[] { R.id.tvTrid, R.id.tvProid, R.id.tvWerkzaamheid, R.id.tvTijd, R.id.tvDatum });
// updating listview
setListAdapter(adapter);
}
});
}
}
}
list_uren.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/tvTrid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone" />
<!-- Name Label -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/tvDatum"
android:layout_width="269dp"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingLeft="6dip"
android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="17sp"
android:visibility="visible" />
<ImageView
android:id="#+id/toevoegen"
android:layout_width="25dp"
android:layout_height="25dp"
android:src="#android:drawable/ic_menu_add" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/tvTijd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="6dip"
android:text="8:00-12:00"
android:textSize="17sp"
android:textStyle="bold"
android:visibility="visible" />
<TextView
android:id="#+id/tvProid"
android:layout_width="138dp"
android:layout_height="wrap_content"
android:layout_marginLeft="25dp"
android:paddingLeft="6dip"
android:text="Project"
android:textSize="17sp" />
</LinearLayout>
<TextView
android:id="#+id/tvWerkzaamheid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="6dip"
android:paddingTop="6dip"
android:text="Werkzaamheid"
android:textSize="17sp" />
</LinearLayout>
all_uren.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<!-- Main ListView
Always give id value as list(#android:id/list)
-->
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
What is the best way to get the date separators? Thank you.
Add this at the end of list_uren.xml before closing the LinearLayout
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#666666" />
You can change the background to whatever you want.

Categories

Resources