How do I add a Progress Bar when a user selects a spinner item that triggers a http request. Do I add it to the class doing the http request (dataCall) or the main activity that has the spinner in it?
I have a class DataCall that when called does a http call to a php script that gets data from a MySQL database and returns data in a JSON format. This class is called after a spinner item is selected. The data returned is added to another spinner in the same activity. I am trying to show the progress wheel when the class DataCall is doing its thing. Below is my code for calling DataCall from my MainActivity and the code from DataCall .
MainActivity that calls DataCall (See below) when the spinner is selected. When DataCall returns data it updates another spinner with the new data.
statespinner.setOnItemSelectedListener(new OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position,long arg3)
{
int id = parent.getId();
if (spinner1_count2 < spinner1_count1 ) {
spinner1_count2++; }
else
{
city.clear();
String item = statespinner.getSelectedItem().toString();
String spinnerContentType = "city";
String spinnerURL = "getStoreCity.php?state=" + item;
//CALLING DATACALL BELOW
String city_data = DataCall.getJSON(spinnerURL,spinnerContentType);
Log.d(TAG, city_data);
String state_spinner_log = "STATE SPINNER";
Log.d(TAG, state_spinner_log);
JSONArray jsonArray;
try {
cityjsonArray = new JSONArray(city_data);
for (int i=0; i<cityjsonArray.length(); i++)
{
String styleValue2 = cityjsonArray.getJSONArray(i).getString(0);
Log.d(TAG, styleValue2);
city.add(styleValue2);
adapter2.notifyDataSetChanged();
}
//
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
// TODO Auto-generated method stub
}
});
DataCall Class:
public class DataCall extends Activity {
private static final String TAG = "MyApp";
public static String getJSON(String myUrlString, String contentType){
String line = null;
String tag_value = null;
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpPost = new HttpGet("http://www.mywebsite.com/getdata/" + myUrlString);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
line = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
line = "<results status=\"error\"><msg>Can't connect to server1</msg></results>";
} catch (MalformedURLException e) {
line = "<results status=\"error\"><msg>Can't connect to server2</msg></results>";
} catch (IOException e) {
line = "<results status=\"error\"><msg>Can't connect to server3</msg></results>";
}catch (Exception anything) {
//Whatever
}
return line;
}
}
I think you're going to have to move this web call out to a different thread as it will take an unknown amount of time to run and may cause an ANR.
If you use ASyncTask it has an inbuilt mechanism for updating a progress bar as the background thread runs. There is a lot of valuable information at this link
http://www.vogella.de/articles/AndroidPerformance/article.html
Hope this helps, m
Related
Sooo here is my OnCreateView code
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_profile, container, false);
tvMemberName = (TextView) v.findViewById(R.id.member_name);
UrlPostHelper uph = new UrlPostHelper();
uph.execute();
return v;
}
and AsyncTask
private class UrlPostHelper extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
String url = "http://localhost:8080/MP/Profile";
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpResponse response;
String data = "no response";
try {
response = httpClient.execute(httpGet);
data = EntityUtils.toString(response.getEntity());
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String s = "yow";
try {
JSONArray ja = new JSONArray(data);
for (int i = 0 ; i < ja.length(); i++ ){
JSONObject j = ja.getJSONObject(i);
String firstName = j.getString("firstName");
String lastName = j.getString("lastName");
System.out.println(firstName);
s = firstName +" " + lastName;
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return s;
}
protected void onPostExecute(String result){
super.onPostExecute(result);
Log.i("TAG", result );
tvMemberName.setText(result);
}
}
My problem is that in my android app it does not show anything at first but after a while like around 1-2 minutes the "yow" will show. It is not replaced with the member name though. I tried running my servlet and it works just fine. Please help me.
AsyncTask<Params, Progress, Result>.
private class UrlPostHelper extends AsyncTask<Void, Void, String>{
private EditText tvMemberName;
public UrlPostHelper(EditText tv){
this.tvMemberName = tv;
}
Return Text after background task finished.
#Override
protected String doInBackground(Void... params) {
HttpResponse response;
String data = "no response";
try {
response = httpClient.execute(httpGet);
data = getJSONString(response.getEntity());
} catch (Exception e) {
e.printStackTrace();
}
return data; //Text to set TvMember Value
}
Get String from response Util.
public String getJSONString(InputStream is) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
return response.toString();
}
Set EditText onPostExecute.
protected void onPostExecute(String result){
Log.i("TAG", result );
tvMemberName.setText(result);
}
Pass EditText with the UrlPostHelper call.
new UrlPostHelper(tvMemberName).excute();
Ive created an app that is just making data accessible on mobile devices. This is what should happen.
1) connect to MySQL db
2) pull data from MySQL db
3) save data to SQLite db
4) display data from SQLite db
This all works good and well when I have net access. but it seems the moment I loose my connectivity I can no longer access data from my SQLite db.... and the whole point of the app is to make data accessible anywhere, with or without internet, hence the local db. Hope someone can help me with this...
public class MainActivity extends Activity {
SQLiteDatabase HRdb;
InputStream isr = null;
String result = "";
TextView resultView;
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HRdb=openOrCreateDatabase("HRdb",MODE_PRIVATE,null);
HRdb.execSQL("CREATE TABLE IF NOT EXISTS HRinfotbl (lname VARCHAR, fname VARCHAR, email VARCHAR, contact VARCHAR);");
try {
result = new httprRequest().execute().get();
HRdb.delete("HRinfotbl", null, null);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
resultView = (TextView) findViewById(R.id.result);
getData();
}
/*
#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;
}
*/
//function to print data from SQLite array
public String SQLitePrint(String n)
{
String info = "";
Cursor c=HRdb.rawQuery("SELECT * from "+n+";", null);
int count = c.getCount();
c.moveToFirst();
for (Integer j = 0; j < count; j++)
{
info = info +
"Surname : "+c.getString(c.getColumnIndex("lname"))+"\n"+
"Name : "+c.getString(c.getColumnIndex("fname"))+"\n"+
"Email : "+c.getString(c.getColumnIndex("email"))+"\n"+
"Contact : "+c.getString(c.getColumnIndex("contact"))+"\n\n";
c.moveToNext() ;
}
HRdb.close();
return info;
}
public String Search(String n)
{
String info = "";
Cursor cu = HRdb.rawQuery("SELECT * FROM HRinfotbl WHERE (lname LIKE '%||"+n+"||%' OR fname LIKE '%||"+n+"||%';",null);
int count = cu.getCount();
cu.moveToFirst();
for (Integer j = 0; j < count; j++)
{
info = info +
"Surname : "+cu.getString(cu.getColumnIndex("lname"))+"\n"+
"Name : "+cu.getString(cu.getColumnIndex("fname"))+"\n"+
"Email : "+cu.getString(cu.getColumnIndex("email"))+"\n"+
"Contact : "+cu.getString(cu.getColumnIndex("contact"))+"\n\n";
cu.moveToNext() ;
}
HRdb.close();
return info;
}
public void getData(){
String name,surname,email,contact;
//parse json data
try {
JSONArray jArray = new JSONArray(result);
for(int i=0; i<jArray.length();i++){
JSONObject json = jArray.getJSONObject(i);
surname = json.getString("surname");
name = json.getString("name");
email = json.getString("email");
contact = json.getString("contact");
HRdb.execSQL("INSERT INTO HRinfotbl VALUES ('"+surname+"','"+name+"','"+email+"','"+contact+"');");
resultView.setText("Succesfully updated your database.");
}
} catch (Exception e) {
// TODO: handle exception
Log.e("log_tag", "Error Parsing Data "+e.toString());
}
}
private class httprRequest extends AsyncTask<String,Integer,String>{
#Override
public String doInBackground(String... params){
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("pvt");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
if(response.getStatusLine().getStatusCode()!=200){
Log.d("MyApp", "Server encontered an error.");
}
HttpEntity entity = response.getEntity();
isr = entity.getContent();
}catch(Exception e){
Log.e("log_entity", "Error in http connection: "+e.toString());
}
//conversion happening here..
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(isr,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
isr.close();
result = sb.toString();
}
catch(Exception e){
Log.e("log_buf", "Error converting result "+e.toString());
}
return result;
}
}
}
here is where I display most data.
public class Human_Resources extends MainActivity{
TextView dbView;
EditText searchtxt;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.human_resources);
dbView = (TextView) findViewById(R.id.showdb);
searchtxt = (EditText) findViewById(R.id.searchtxt);
dbView.setMovementMethod(new ScrollingMovementMethod());
dbView.setText(SQLitePrint("HRinfotbl"));
Button search = (Button) findViewById(R.id.searchbtn);
search.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v)
{
dbView.setText(Search(searchtxt.getText().toString()));
}
});
}
}
also I am very new to android, started last week. So just keep that in mind when giving an answer ;) thanks!
here is my error log. regarding when I try display for SQLite. db
01-15 08:47:16.856: W/ResourceType(7501): Failure getting entry for 0x01080a03 (t=7 e=2563) in package 0 (error -75)
01-15 08:47:16.876: E/log_entity(7501): Error in http connection: java.net.UnknownHostException: Unable to resolve host "www.deltabec.com": No address associated with hostname
01-15 08:47:16.876: E/log_buf(7501): Error converting result java.lang.NullPointerException: lock == null
01-15 08:47:16.876: E/log_tag(7501): Error Parsing Data org.json.JSONException: End of input at character 0 of
The reason is that you are deleting the table in main activity without checking. The following lines are the problem for you. What is happening here is you delete the table data, when ever you start your app. So don't delete the table data blindly unless you dont have internet connection.
try {
result = new httprRequest().execute().get();
HRdb.delete("HRinfotbl", null, null);// This cause the problem.
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
You can check for the internet if internet is avialable then delete and get the data otherwise dont delete the data so you might check here
so you have to check here like
try {
result = new httprRequest().execute().get();
// A work around to fix the problem
if(internet avialable) {
HRdb.delete("HRinfotbl", null, null);
} else {
getData();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I'm trying to print The destination addresses & their distances from the origin in the textView. However, I keep getting error or just show the last value. I don't want the text view get updated, I want the new value to be printed under the new one
Here is my code
public class MainActivity extends Activity {
private static final String TAG_ROWS = "rows";
private static final String TAG_ELEMENTS = "elements";
private static final String TAG_DISTANCE = "distance";
private static final String TAG_VALUE = "value";
private static final String TAG_ADDRESS = "destination_addresses";
String Addresses[]= {"2906+west+Broadway+Vancouver+BC","4750+Kingsway+Burnaby+BC","2633+Sweden+Way+110+Richmond","943+Marine+Dr+North+Vancouver","4567+Lougheed+Hwy+Burnaby"};
String data;
HttpClient client;
double minDistance=0;
static JSONObject jObj = null;
String destination_addresses;
JSONArray rows;
String destination;
String distanceStr;
String[] value_destination;
String value;
final static String URL= "http://maps.googleapis.com/maps/api/distancematrix/json?";
TextView result;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
result = (TextView) findViewById(R.id.text1);
result.setText("Distace from the location" + destination + " is :" + distanceStr );
new TestGoogleMaps().execute("");
}
public class TestGoogleMaps extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
try {
try {
ClosestObject();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
finally {
}
return null;
}
#Override
protected void onPostExecute(String resuls) {
// TODO Auto-generated method stub
super.onPostExecute(resuls);
}
}
public void ClosestObject() throws JSONException, ClientProtocolException, IOException {
// Creating JSON Parser instance
StringBuilder url = new StringBuilder(URL);
client=new DefaultHttpClient();
for (int index=0; index<Addresses.length; index++){
String str_parameters = "origins="+ URLEncoder.encode("1359+Richards+Street+Vancouver+BC","UTF-8")+"&destinations="+ URLEncoder.encode(Addresses[index],"UTF-8")+"&mode=driving&language="+ URLEncoder.encode("en-FR","UTF-8")+"&sensor=false";
System.out.println("URL URl :: "+url+str_parameters);
HttpGet get = new HttpGet(url+str_parameters);
get.setHeader("Accept", "application/json");
get.setHeader("Content-type", "application/json");
HttpResponse r = client.execute(get);
HttpEntity en = r.getEntity();
data = EntityUtils.toString(en);
System.out.println("ClosestObject Response :: "+data);
try {
jObj = new JSONObject(data);
destination = jObj.getString("destination_addresses");
// printing the destination and checking wheather parsed correctly
Log.v("Destination", destination);
JSONArray jarRow = jObj.getJSONArray("rows");
for(int i=0;i<jarRow.length(); i++){
// creating an object first
JSONObject ElementsObj = jarRow.getJSONObject(i);
// and getting the array out of the object
JSONArray jarElements = ElementsObj.getJSONArray("elements");
for(int j=0; j<jarElements.length(); j++){
JSONObject distanceObj = jarElements.getJSONObject(j).getJSONObject("distance");
distanceStr = distanceObj.getString("value");
Log.v("finally getting distance : ", distanceStr);
} }
} catch (JSONException e) {
e.printStackTrace();
}
}
}
#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;
}
}
How can I print all the members on my TextView?
I want the new value to be printed under the new one
So if you want to print your all destinations into TextView most efficient way will be to use for example StringBuffer to create whole String that will be finally assigned to your TextView.
I recommend you change your return type of ClosestObject method to StringBuffer(or Builder) and in your loop append data to it. Also change third parameter of AsyncTask to StringBuffer.
Pseudo-code:
#Override
protected StringBuffer doInBackround() {
...
StringBuffer buff = ClosestObject();
return buff;
}
In your ClosestObject method:
StringBuffer buff = new StringBuffer();
for (int i = 0; i < arr.length(); i++) {
// getting values from JSON
buff.append(value).append("\n"); // buff.append(value1 + "," + value2 + "\n")
}
...
return buff;
and finally update your TextView from onPostExecute() method that already runs on UI Thread and allows updates.
yourTextView.setText(result.toString());
Note:
Don't forget that by naming conventions in Java, method's signature should start with lowercase letter and not with uppercase.
Try this:
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
result.setText(result.getText().toString() + "\n" + distanceStr);
}
});
You must update the TextView on the UI Thread as shown because the JSON response is received in a different Thread from your AsyncTask, otherwise you will receive a CalledFromTheWrongThreadException.
I'm getting strings from a HttpGet and I want to place them into the listview. How could I do this? I can't find any information on it anywhere. At the movement, I just have some test data in place.
Eg.
"Test1"
But I want it to be dynamic, from the strings the phone get's from the HttpGet.
Thanks.
My Code so far: (Apologies for the code being messy, I'll rewrite it soon!)
public class ChatService extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chatservice);
try {
ContactsandIm();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
CheckLogin();
ListView list = (ListView) findViewById(R.id.ListView01);
list.setClickable(true);
final List<PhoneBook> listOfPhonebook = new ArrayList<PhoneBook>();
listOfPhonebook.add(new PhoneBook("a", "9981728", "test#test.com"));
listOfPhonebook
.add(new PhoneBook("Test1", "1234455", "test1#test.com"));
listOfPhonebook.add(new PhoneBook("Test2", "00000", "test2#test.com"));
PhonebookAdapter adapter = new PhonebookAdapter(this, listOfPhonebook);
list.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View view,
int position, long index) {
System.out.println("sadsfsf");
showToast(listOfPhonebook.get(position).getName());
}
});
list.setAdapter(adapter);
}
private void CheckLogin() {
// TODO Auto-generated method stub
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
/* login.php returns true if username and password is equal to saranga */
HttpPost httppost = new HttpPost("http://gta5news.com/login.php");
try {
// Execute HTTP Post Request
Log.w("HttpPost", "Execute HTTP Post Request");
HttpResponse response = httpclient.execute(httppost);
String str = inputStreamToString(response.getEntity().getContent())
.toString();
Log.w("HttpPost", str);
if (str.toString().equalsIgnoreCase("true")) {
Log.w("HttpPost", "TRUE");
try {Thread.sleep(250);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//put intent here(21/3/12);
} else {
Log.w("HttpPost", "FALSE");
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private StringBuilder inputStreamToString(InputStream is) {
String line = "";
StringBuilder total = new StringBuilder();
// Wrap a BufferedReader around the InputStream
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
// Read response until the end
try {
while ((line = rd.readLine()) != null) {
total.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// Return full string
return total;
}
private void ContactsandIm() throws URISyntaxException, ClientProtocolException, IOException {
// TODO Auto-generated method stub
BufferedReader in = null;
String data = null;
HttpClient get = new DefaultHttpClient();
URI website = new URI("http://www.gta5news.com/test.php");
HttpGet webget = new HttpGet();
webget.setURI(website);
HttpResponse response = get.execute(webget);
Log.w("HttpPost", "Execute HTTP Post Request");
in = new BufferedReader (new InputStreamReader(response.getEntity().getContent()));
//now we'll return the data that the PHP set from the MySQL Database.
// just some test code, to see if the HttpGet was working.
if (in.equals("True")); {
Toast.makeText(this,"yay", Toast.LENGTH_LONG).show();
}
}
// end bracket for "ContactsandIm"
private void showToast(String message) {
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
}
}
From the code, i see that PhonebookAdapter is your custom adapter class. Why not parse the http response of type PhoneBook and add it to listOfPhonebook. That should show the parsed contents in the listView.
As I understand you need to add new PhoneBook entry every time your Http request is succeeded.
If so, you have to options to make everything dynamic:
Recreate adapter every time you receive new portion of data:
Make your listView global variable (to make it accessible from any function within the class)
Do the same with your List
Once you have received new portion of data - add this data to your List, create new adapter and set this adapter to your ListView
Create a custom adapter with possibility to update ListItems:
public class YourCustomAdapter extends BaseAdapter
{
private final LayoutInflater inflater;
private ArrayList list = new ArrayList();
private Handler uiHandler = new Handler();
/*..... default set of functions from BaseAdapter ......*/
public void setList(ArrayList<PhoneBook> list)
{
this.list = list;
}
public void addEntry(final PhoneBook entry)
{
uiHandler.post(new Runnable()
{
#Override
public void run()
{
list.add(entry);
YourCustomAdapter.notifyDataSetChanged();
}
});
}
}
please note that in this case you are allowed to modify underlying list ONLY from UI thread
Hope this helps
class XXX implements Runnable
{
String lat,lon,str,taluka_name;
int name;
HttpResponse response;
HttpEntity entity;
InputStream is = null;
Toast s1;
StringBuilder sb=null;
TextView v;
Spinner s;
public String result[];
TextView tv;
LinearLayout ll1;
int i;
ArrayList<Integer> croplist;
public XXX(String t_n,String [] res,LinearLayout ll,TextView tv1)
{
croplist= new ArrayList<Integer>();
taluka_name = t_n;
result = res;
ll1= ll;
tv = tv1;
}
#Override
public void run() {
// TODO Auto-generated method stub
HttpClient httpclient = new DefaultHttpClient();
HttpPost request = new HttpPost("http://10.0.2.2/proagri115.php");
List<NameValuePair>login=new ArrayList<NameValuePair>();
login.add(new BasicNameValuePair("location", taluka_name));
try
{
UrlEncodedFormEntity entity=new UrlEncodedFormEntity(login);
request.setEntity(entity);
}
catch (UnsupportedEncodingException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
try
{
response = httpclient.execute(request);
entity = response.getEntity();
is = entity.getContent();
System.out.println("Executed the request");
}
catch (ClientProtocolException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
e.printStackTrace();
System.out.println("");
}
catch(Exception e)
{
}
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
String line="0";
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
is.close();
str=sb.toString();
Log.e("log_tag", "Success converting result "+sb.toString());
}
catch(Exception e)
{
Log.e("log_tag", "Error converting result "+e.toString());
System.out.println(str+"I have executed");
result = str.split(">>");
System.out.println("length"+result.length);
for(i=0;i<result.length;i++)
{
System.out.println("\n"+i+"=="+result[i]);
}
System.out.println("Notified");
}
}
}
public class help extends Activity{
int j;
Intent i;
String s,taluka_name;
EditText edt,edt1,edt2;
Double lat,lon;
Spinner spin;
String [] re;
TextView tv;
Layout lt;
LinearLayout lt1;
XXX runnable;
public void onCreate(Bundle savedinstancestate)
{
super.onCreate(savedinstancestate);
setContentView(R.layout.help);
lt1 = (LinearLayout)findViewById(R.id.ll1);
s =(String)getIntent().getSerializableExtra("Rainfall");
taluka_name =(String)getIntent().getSerializableExtra("location");
System.out.println(s);
tv = new TextView(this);
tv.setText("Crops for Your Selected Area are");
lt1.addView(tv);
try
{
runnable = new XXX(taluka_name,re,lt1,tv);
Thread threadX = new Thread(runnable);
System.out.println("till this");
threadX.start();
System.out.println("In Waited");
try
{
wait(500);
}
catch (IllegalMonitorStateException e)
{
System.out.println("IllegalMonitorStateException");
}
catch (InterruptedException e)
{
System.out.println("InterruptedException");
}
System.out.println("Out of Waited");
}
catch(Exception e)
{
System.out.println("Error again "+e);
}
try{
System.out.println("Final Result will be");
for(j=0;j<runnable.result.length;j++)
{
tv = new TextView(this);
tv.setText(runnable.result[j]);
System.out.println(runnable.result[j]);
lt1.addView(tv);
}
}
catch(Exception e)
{
}
}
}
I have main activity and thread XXX. I want to use the result of httprequest in XXX thread to be used in Main activity.But before XXX completes its operation main thread executes and
I get NullpointerException . How should I use network response in main activity . I have tried "synchronized block" . But It works for methods of single class.
How should I solve this problem?
You should use a synchronization mechanism whenever two threads need to cooperate and exchange information.
You can use a Handler to post an action back to the UI thread when the HTTP request completes in the background thread or better yet perform the background work in AsyncTask.
Here is a general example:
private class AsyncTaskExample extends AsyncTask<Param, Progress, Result> {
#Override
protected Result doInBackground(Param... params) {
// Performs some computation in a background thread.
// Use publishProgress() to publish progress updates which
// will take place in the UI thread in onProgressUpdate().
return ...;
}
#Override
protected void onProgressUpdate(Progress... progress) {
// Update progress information. Run in the UI thread.
}
#Override
protected void onPostExecute(Result result) {
// Update on completion. Run in the UI thread.
}
}
Note that AsyncTask is a generic class and requires three parameters: Param for input data to the background computation, Result for the result of the computation and Progress to represent progress update information.
Note also that doInBackground() is the only abstract method in AsyncTask, so at minimum you must override just this one method. In most cases, you will find onPostExecute() and onProgressUpdate() very useful as well. For more overridable methods and details see AsyncTask.
Once you have defined a task class you can launch the computation it represents in the background by in the following way:
new AsyncTaskExample().execute(param1, param2, ...);
Passing parameters (of type Param) to execute(). Note that this must be done in the UI thread.
At minimum, you need to use Thread.join to wait for the thread to complete.. But that would block on your UI thread which is really bad. You should really just do this the android way and use an AsyncTask
Read this:
http://developer.android.com/resources/articles/painless-threading.html
Here is what you should do:
import android.os.AsyncTask;
public class XXX extends AsyncTask<Integer, Integer, String[]> {
String lat, lon, str, taluka_name;
int name;
HttpResponse response;
HttpEntity entity;
InputStream is = null;
Toast s1;
StringBuilder sb = null;
TextView v;
Spinner s;
public String result[];
TextView tv;
LinearLayout ll1;
int i;
ArrayList<Integer> croplist;
public XXX(String t_n, String[] res, LinearLayout ll, TextView tv1) {
croplist = new ArrayList<Integer>();
taluka_name = t_n;
result = res;
ll1 = ll;
tv = tv1;
}
#Override
protected String[] doInBackground(Integer... params) {
// TODO Auto-generated method stub
HttpClient httpclient = new DefaultHttpClient();
HttpPost request = new HttpPost("http://10.0.2.2/proagri115.php");
List<NameValuePair> login = new ArrayList<NameValuePair>();
login.add(new BasicNameValuePair("location", taluka_name));
try {
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(login);
request.setEntity(entity);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
response = httpclient.execute(request);
entity = response.getEntity();
is = entity.getContent();
System.out.println("Executed the request");
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
e.printStackTrace();
System.out.println("");
} catch (Exception e) {
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
String line = "0";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
str = sb.toString();
Log.e("log_tag", "Success converting result " + sb.toString());
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
System.out.println(str + "I have executed");
result = str.split(">>");
System.out.println("length" + result.length);
for (i = 0; i < result.length; i++) {
System.out.println("\n" + i + "==" + result[i]);
}
System.out.println("Notified");
}
return result;
}
}
Then from your activity call:
new XXX(taluka_name,re,lt1,tv).execute();
Now the tricky thing is you need to get that result back to your UI thread.. The easiest way is to put the AsyncTask within the activity as an inner class, then in onPostExecute of the asyncTask you just call some function from your activity.
If you want the AsyncTask in a seperate file then you need to pass a reference of your class to the constructor of the AsyncTask and then you can call any public method of your activity from the asyncTask. Just remember that you can only call the activities methods in onPostExecute and in onProgressUpdate (do not call UI methods in doInBackground)