AsyncTask give lag for the task - android

My project is to get data from database to my listview in my project. It get data but when I close and run the application more than one time it gives lag(the data is hidden but when I scroll the list view it show out)
my code is
private class SendfeedbackJob extends AsyncTask<String, Void, String> {
String page="";
protected String doInBackground(String...params) {
// do above Server call here
BufferedReader in = null;
try {
HttpClient client = new DefaultHttpClient();
HttpPost request = new HttpPost(
"http://192.168.43.16/marche/category_display.php");
HttpResponse response = client.execute(request);
in = new BufferedReader(
new InputStreamReader(
response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
page = sb.toString();
String [] s= page.split(System.getProperty("line.separator"));
for(int i=0;i<s.length;i++){
Cat_Name[i]=s[i];
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return page;
}
#Override
protected void onPostExecute(String message) {
//process message
Log.d("MyAsyncTask", "Received result: " + message);
}
}
and the on the oncreate method
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SendfeedbackJob pro=new SendfeedbackJob();
pro.execute();
}

The data is hidden. because, obviously you are not waiting until doInBackground to finish processing before you refresh the adapter (Cats array is still empty). when you scroll down few seconds later the list view will ask the adapter for the data in the bottom cells and scrolling up before the list view asks for the top cells and they just get displayed.
You must set your adapter or calling notifyDataSetChanged in
onPostExecute method.

Call notifydatasetchanged method in the UI thread after fetching all the data
While fetching the data show progress bar to avoid some bad UI experience if the process takes a lot of time

Related

Call Async Webservice From For Loop

When I call a webservice from a for loop to insert/update data into MySQL using PHP only the last item gets inserted/updated because (i think) the for loop completes quicker than the webservice, how can I delay my for loop or achieve a webservice call for each item returned in the for loop one after another.
For Loop Code:
for (int i = 0; i < lv.getCount(); i++) {
view = lv.getAdapter().getView(i, lv.getChildAt(i), lv);
if (view != null) {
// Getting my views
tvItem = (TextView) view.findViewById(R.id.tvItem);
strItem = tvItem.getText().toString();
//Call AsyncTask
accessWebService();
}
}
Webservice:
private class Webservice extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(params[0]);
try {
HttpResponse response = httpclient.execute(httppost);
jsonResult = inputStreamToString(response.getEntity().getContent()).toString();
}
catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private StringBuilder inputStreamToString(InputStream is) {
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = rd.readLine()) != null) {
answer.append(rLine);
}
}
catch (IOException e) {
}
return answer;
}
#Override
protected void onPostExecute(String result) {
try{
ld();
}catch (Exception e){
}
}
}// end async task
public void accessWebService() {
Webservice task = new Webservice();
//Update MySQL Using PHP
}
When you want to insert/update all data from for loop you must use callback like interfaces. Once you implement this it will wait for completing the process. Once completed it will call success or error method. Based on this you insert/update another record.
interface DataCallback {
fun onSuccess(result: Any)
fun onError(error: Any)
}
public void getCountries(new DataCallback(){
#Override
public void onSuccess(Object result){
// insert/update next record
}
#Override
public void onError(Object error){
// show error message
}
});
This is just example. You should convert it based on your need. Thanks.

Screen freezes when downloading content from server in android

I am downloading JSON Content from server in the MainActivity and passing the JSON from MainActivity to ListActivity, the problem here is I have added a sleep time of 10s in the backend server i.e. Php from where the data is fetched. Since, the response will the delayed I would expect that screen opens and waits until the response comes and move to next screen.
But what is happening is the screen goes white/black completely untill the response is recieved and ListActivity is loaded, the problem here is the MainActivity is never visible. Below is code for the same:
MainActivity
JSONData jsonData = new JSONData();
String jsonList = jsonData.fetchList();
Intent intent = new Intent(getApplicationContext(),ListActivity.class);
intent.putExtra("jsonList",jsonList);
startActivity(intent);
finish();
JSON Data class
public String fetchList() {
try {
String list = new DownloadJSONData().execute(listURL).get().toString();
return list;
} catch (Exception e) {
return "";
}
}
private class DownloadJSONData extends AsyncTask<String, String, String> {
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return "";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
you are using get() method which accquires the main thread or ui thread untill the async task is completed
you should avoid using get() and also can use progress dialog in onPreExecute for displaying progression on network call to user

HttpURLConnection crashes application

I want to receive and send data with a web server but the code does not work
What do I do for this code to work?
Note this code inside onCreate
try {
URL url = new URL("http://myweb.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream Stream = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(Stream);
BufferedReader b = new BufferedReader(reader);
StringBuilder s = new StringBuilder();
String str ="";
while ((str = b.readLine())!=null) {
s.append(str);
}
String data = s.toString();
TextView myText = (TextView) findViewById(R.id.Text);
myText.setText(data);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Make sure that you do network-related tasks on a separate thread in Android. Also, check that you have the INTERNET permission set.
If you want to then update the UI from another thread, you have to use
runOnUiThread (new Runnable () {
public void run() {
//update ui in here
}
}
All your code runs in Main thread which should be always used for setting up the UI and to listen for UI events such as on click listeners.
Network calls are not allowed on this thread as they might take long time. Use AsyncTask API of android which is designed for running code in separate thread.
Create a class like one below for all GET request tasks.
public class DownloadTask extends AsyncTask<String, Void, Integer> {
private String TAG = "InDownloadTask";
private DownloadCallback callback;
private String data;
public DownloadTask(DownloadCallback cb){
callback = cb;
}
#Override
protected Integer doInBackground(String... params) {
Integer result = 0;
HttpURLConnection urlConnection;
try {
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
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);
}
data = response.toString();
result = 1;
} else {
result = 0;
}
} catch (Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
return result;
}
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
callback.onFinishDownload(data, integer);
}
}
Create a callback interface that we use for the above class.
public interface DownloadCallback {
public void onFinishDownload(String data, Integer result);
}
Now from your activity onCreate
String url = "http://myweb.com/";
new DownloadTask(new DownloadCallback() {
public void onFinishDownload(String data, Integer result) {
if(result == 1)
myText.setText(data);
else
myText.setText("Error");
}
}).execute(url);
If you have many network related operations, use a Network library such as Volley which will take care of this.

Retrieving data from a website not working (Android)

I use the following class to retrieve data from a website:
public class GetMethodEx {
public String getInternetData() throws Exception {
BufferedReader in = null;
String data = null;
try {
HttpClient client = new DefaultHttpClient();
URI website = new URI("http://www.google.com");
HttpGet request = new HttpGet();
request.setURI(website);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.separator");
while ((l = in.readLine()) != null) {
sb.append(l + nl);
}
in.close();
data = sb.toString();
return data;
} finally {
if (in != null) {
try {
in.close();
return data;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
And the following class uses the above class to print the retrieved data on the screen:
public class HttpExample extends Activity {
TextView httpStuff;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.httpex);
httpStuff = (TextView) findViewById(R.id.tvHttp);
GetMethodEx test = new GetMethodEx();
String returnedData = null;
try {
returnedData = test.getInternetData();
httpStuff.setText(returnedData);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I have set the "httpStuff" TextView to "loading..." in the "httpex" xml. Now the problem I am facing is that when I run the app, it is stuck at this "loading..." forever. Any ideas why?
Thanks.
PS: I have added the permission "android.permission.INTERNET" in the manifest.
EDIT: Actually I have a duplicate question which has the correct solution. Anyway, thanks!
Make sure to check LogCat to look for potential error messages. I'm guessing you didn't request the Internet permission in your AndroidManifest.xml.
Add
<uses-permission android:name="android.permission.INTERNET" />
outside the application tag in your AndroidManifest.xml
Edit:
Also, you should avoid running network requests on the UI thread. On later versions of android (Honeycombe and later I believe) you'll get a NetworkOnMainThreadException, which could also cause the issue you're facing.
Try using an AsyncTask to run this request. See the answer here:
How to fix android.os.NetworkOnMainThreadException?

setText from a parsed JSON object with AsyncTask [duplicate]

This question already has answers here:
AsyncTask Android example
(21 answers)
Closed 9 years ago.
Im making an android program that parses JSON texts from a source code of a webpage in the internet. It is working in android 2.2 but I need it now to be on android 3.0, which needs to be on the AsyncTask. I have a background about AsyncTask but I'm so confused where to put this and that. Thanks in advance everyone :)
Here is my method in the MainActivity class:
private void jsonStuffs() {
//JSON PARSER & HOME PAGE TEXTVIEWS
client = new DefaultHttpClient();
GetMethodEx test = new GetMethodEx();
String returned;
try {
returned = test.getInternetData();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try{
String jsonStr = test.getInternetData(); //go to GetMethodEx
JSONObject obj = new JSONObject(jsonStr);
//////////////////////find temperature in the JSON in the webpage
String temperature = obj.getString("temperature");
TextView tvTemp = (TextView)findViewById(R.id.textView);
tvTemp.setText(temperature);
}
//catch (JSONException e) {
// e.printStackTrace();
//}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The GetMethodEx class is this (this will find the link of the webpage then convert it's source code to text format):
public class GetMethodEx extends Activity {
public String getInternetData() throws Exception{
BufferedReader in = null;
String data = null;
//
try{
HttpClient client = new DefaultHttpClient();
URI website = new URI("http://nhjkv.comuf.com/json_only.php");
HttpGet request = new HttpGet();
request.setURI(website);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String l = "";
String nl = System.getProperty("line.separator");
while ((l = in.readLine()) !=null){
sb.append(l + nl);
}
in.close();
data = sb.toString();
return data;
}finally {
if (in !=null){
try{
in.close();
return data;
} catch (Exception e){
e.printStackTrace();
}
}
}
}
}
You can do something like this (this code is just for illustration, change it as needed)
class MyAsyncTask extends AsyncTask<String, Void, JSONObject> {
protected void onPreExecute() {
// You can set your activity to show busy indicator
//setProgressBarIndeterminateVisibility(true);
}
protected JSONObject doInBackground(String... args) {
return jsonStuffs();
}
protected void onPostExecute(final JSONObject jsonObj) {
String temperature = jsonObj.getString("temperature");
TextView tvTemp = (TextView)findViewById(R.id.textView);
tvTemp.setText(temperature);
// Stop busy indicator
//setProgressBarIndeterminateVisibility(false);
}
To call this task use new MyAsyncTask().execute(); (you can pass String parameters to execute if needed)
You can change your jsonStuffs() to return JSONObject
e.g.
private JSONObject jsonStuffs() {
// ...
String jsonStr = test.getInternetData(); //go to GetMethodEx
return new JSONObject(jsonStr);
// ...
}
It is working in android 2.2 but I need it now to be on android 3.0,
which needs to be on the AsyncTask.
=> Yes it gives NetworkOnMainThreadException in 3.0 if you make web call without implementing inside Thread such as AsyncTask.
I have a background about AsyncTask but I'm so confused where to put
this and that.
=> Simply include web call logic inside doInBackground() method of the AsyncTask, in your case call getInternetData() inside doInBackground().
FYI, you can't update UI straight way while doing long running task inside the doInBackground(). Yes if you want to update UI then do follow any of the below:
Update UI from the onPostExecute() method.
or implement runOnUiThread() inside the doInBackround()

Categories

Resources