I am trying to get some text via HTTP GET and display it to the UI. I do not need an async task (i.e, the user have to wait until I get the text completely).
I tried this in main thread
try {
String url = URL_HERE;
HttpGet httpget = new HttpGet (url);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
text = Client.execute(httpget, responseHandler);
}
catch(Exception ex) {
text = ex.getLocalizedMessage();
}
But I always see an exception.
I just need a simple mechanism to get the text. Could you suggest?
Thank you very much,
You should use AsyncTask but if you have to use a sync method
try
String resut = execute().get().toString();
it will freeze the UI(without application is not responding) till you got the message from httpget
All networking has to be in a separate thread by Android's design. It is very possible that the request will take some time and the user has to be bothered by waiting as little as possible. So, you will have to use an AsyncTask or similar.
You should use a ASyncTask so the UI thread doesn't freeze. If the UI thread freezes, Android will show an "Application not responding" dialog to the user, so it's important that you do your call in a ASyncTask even if you don't want your user to use the UI while you are doing it.
You can "block" the UI overriding the onPreExecute method in the ASyncTask (to show a progress dialog for example) then "unblock" it overriding the onPostExecute method (to remove the progress dialog for example).
You should always use AsyncTask to perform the network operations
in android
Because anything that takes more time to load to the UI will lead to
"Unresponsive of the android application"(ANR)
Sample::
public class FrgLatein extends Fragment {
//New-Instance
public static FrgLatein newInstance(){
Log.d("FrgLatein", "newInstance");
FrgLatein fragment = new FrgLatein();
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d("FrgLatein", "onCreateView");
View view=inflater.inflate(R.layout.frg_latein, container, false);
setHasOptionsMenu(true);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
Log.d("FrgLatein", "onActivityCreated");
super.onActivityCreated(savedInstanceState);
}
#Override
public void onStart() {
Log.d("FrgLatein", "onStart");
super.onStart();
new LongOperation1().execute("");
}
private class LongOperation1 extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
// Do the Web service long run here
try {
String url = URL_HERE;
HttpGet httpget = new HttpGet (url);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
text = Client.execute(httpget, responseHandler);
}
catch(Exception ex) {
text = ex.getLocalizedMessage();
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
// Do the UI-task here
}
#Override
protected void onPreExecute() {
// Do the UI-task here
}
#Override
protected void onProgressUpdate(Void... values) {
// Do the UI-task here which has to be done during backgroung tasks are running like a downloading process
}
}
}
Related
I want to show progressbar where image downloaded and set custom color
I do it in onProgressUpdate() but it dosent work it also doesn't appear in logcat.. it also shows a white screen until download completed and if I press back button during the download, it will crash.
my code:
public class DownloadImage extends AsyncTask<String ,Void, Bitmap> {
Bitmap bit;
#Override
protected Bitmap doInBackground(String... urls) {
try {
URL url = new URL(urls[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.connect();
return BitmapFactory.decodeStream(connection.getInputStream());
} catch(Exception e){
Log.i("error download", "doInBackground: "+e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
Log.i("download", "onPostExecute: ");
imageView.setImageBitmap(bitmap);
progressBar.setVisibility(View.GONE);
}
#Override
protected void onProgressUpdate(Void... values) {
Log.i("download", "onProgressUpdate: ");
imageView.setColorFilter(R.color.imagecolor);
}
}
and onCreate() method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
imageView = findViewById(R.id.imageView2);
progressBar = findViewById(R.id.progressBar2);
DownloadImage downloadImage = new DownloadImage();
downloadImage.execute("https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRaL6woz3RgMF-UXU682S_BYb1ayl5xaVancp0PPvF2HnCDmPsb");
try {
downloadImage.get();
} catch (Exception e){
}
}
I want to show progressbar where image downloaded and set custom color I do it in onProgressUpdate() but it dosent work
You need to call publishProgress() from doInBackground(). That will trigger calls to onProgressUpdate(). You are not doing this, and so onProgressUpdate() will not be called.
it also shows a white screen until download completed
Remove your downloadImage.get(); call. That will block the main application thread, and the point of using AsyncTask (or its more modern replacements) is to not block the main application thread.
and if I press back button during the download, it will crash.
If the activity/fragment is destroyed, you should not update the UI. So, you need to confirm in onPostExecute() whether it is safe to update the UI (e.g., call isDestroyed() on the activity).
Beyond that, use Logcat to examine the stack trace associated with any crashes.
i am trying to make an application where asynctask is used to continously update a textview in my main interface. There is another button which opens another activity. When i start the application, the asyntask starts and displays data to the textview but when i click on the other button to open another activity and click on back button to return to the previous activity where the aysnctask was running, it stopped displaying data to the textview.
Could you help mem with this problem or suggest alternative ways. Thank you.
Code for MainActivity:
Button about;
TextView tempData;
Context context = this;
AllSensorData sensorData;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
about=(Button)findViewById(R.id.hAbout);
tempData=(TextView)findViewById(R.id.tempData);
sensorData=new AllSensorData(tempData,getApplicationContext());
sensorData.execute("http://192.168.1.177/");
about.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
Intent i =new Intent(getApplicationContext(),AboutActivity.class);
startActivity(i);
}
});
Code for aynctask class:
public class AllSensorData extends AsyncTask<String, byte[], String>{
TextView temp;
Context context;
public AllSensorData(TextView temp,Context context) {
this.temp=temp;
this.context=context;
}
InputStream nis;
OutputStream nos;
BufferedReader in;
DefaultHttpClient httpclient =new DefaultHttpClient();
URL url;
URLConnection urlconn=null;
InputStreamReader isn;
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
try {
//this method is working for data only
while(true){//while connected
HttpGet httpget =new HttpGet("http://192.168.1.177/");
response = httpclient.execute(httpget);
in=new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String msgFromServer = in.readLine();//read the lines coming from the socket
byte[] theByteArray = msgFromServer.getBytes();//store the bytes in an array
publishProgress(theByteArray);//update the publishProgress
if(isCancelled()){
break;
}
}
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
return null;
}
private boolean alreadyDisplayedNotification = false;
private boolean already =false ;
protected void onProgressUpdate(byte[]... values) {
super.onProgressUpdate(values);
String command=new String(values[0]);//get the String from the recieved bytes
String[] parts= command.split(",");
String part1=parts[0];
temp.setText(part1);
}
}
Read about the activity state saving and recreation of Activity
http://developer.android.com/training/basics/activity-lifecycle/recreating.html
Go through this save instance state to understand why your value in text is not showing
put your "refresh" code inside of onStart() instead of onResume(). onStart() gets "Called when the activity is becoming visible to the user."
Go through Activity life cycle
I got some trouble using the asynctask to query in my cloud database.
Due the response delay to query I cant get the result correctly. Getting NULL.
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
this.mBox = new Box();
super.onCreate(savedInstanceState);
setContentView(R.layout.novomenu_layout);
InicializaAzure(); // init connection to azure mobile service
this.mPalletDao = new PalletDAO(this);
this.mBoxDao = new BoxDAO(this);
mBox = mBoxDao.AzureGetBoxById(1); // query the cloud database
}
BoxDAO.java
public Box AzureGetBoxById(final long id){
final Box[] box = new Box[1];
final boolean[] flag = {false};
new AsyncTask<Void, Void, Void>() {
private ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(mContext);
pDialog.setMessage("Just a moment...");
pDialog.setIndeterminate(true);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
try {
final MobileServiceList<Box> result = mBoxTable.where().field("id").eq(id).execute().get();
Box mBox = result.get(0);
box[0] = mBox;
} catch (Exception exception) {
//createAndShowDialog(exception, "Error");
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
pDialog.dismiss();
flag[0] = true;
}
}.execute();
return box[0];
//return null;
}
I am getting always NULL until the asynctask has finished. but I need the result in the same time.
How can I solve that? I've searched about asynctask but I didnt find anything like this.
Thank you.
Your code is correct, and it works fine. However, if you want to get the result to show in the same time of UI displayed, you can not solve it easily by using the asynctask.
Per my experience, there are two ways can help solve that.
Remove the asynctask code and use the sync method to get data, but it will cause UI hang so that it not be recommended.
Use MobileServiceSyncTable to enable offline sync to solve it.
There is a sample doc https://azure.microsoft.com/en-us/documentation/articles/mobile-services-android-get-started-offline-data/ to help adding offline data sync into your app.
You alse can watch some vedio to learn it, please move to http://channel9.msdn.com/Shows/Cloud+Cover/Episode-155-Offline-Storage-with-Donna-Malayeri and http://azure.microsoft.com/documentation/videos/azure-mobile-services-offline-enabled-apps-with-donna-malayeri/.
I am encountering a problem in my Android application. I am creating a currency converter. I need to create a progressdialog that appears when you convert a value from one currency to another.
Here is part of my code:
if (text1.equals("US Dollar - USD") && text2.equals("Euro - EUR") && edittextdollars.length() > 0 && edittexteuros.length()==0) {
dialog1 = ProgressDialog.show(getActivity(), "", "Calculating...");
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try{
convertvalues("USD", "EUR");
handler.sendEmptyMessage(0);
}
catch (Exception e) {
edittexteuros.setText("Error");
}
}
});
thread.start();
}
private Handler handler = new Handler () {
public void handleMessage(android.os.Message msg) {
switch (msg.what) {
case 0:
dialog1.dismiss();
break;
}
}
};
The progressdialog comes up and goes away, but nothing happens in the background. Here are a few pics of what my app looks like:
This is before the progressdialog comes.
When I press calculate:
After the progressdialog finishes:
As you can see, after the progressdialog goes away, my values don't convert.
In my code,
convertvalues("USD", "EUR");
just gets actual currency value from the internet and multiplies it with the value in my edittext. There is nothing wrong with it and it worked without the progressdialog. I have tested it many times myself.
What am I doing wrong here? I have checked Google for over a week, but I could not find a single solution. Any help regarding this problem is greatly appreciated.
Just like how you update your progressdialog in a handler, you must also update EditTexts in the handler (as it must run on the UI thread). So ideally you would return the result from convertvalues and then pass it to the handler via a message.
From what I can see, your code is fine but you aren't updating the TextView/EditText values when you dismiss the dialog. This means that although it looks like nothing is happening, it actually is - you just aren't updating to see the results.
So, assuming convertvalues() has the converted values stored somewhere, before you call dismiss() you should set your TextViews based on those values.
you can use asynctask in android
see following code may be it will help you..
private class asyncTask extends AsyncTask<Void, Void, Boolean>
{
Context context;
ProgressDialog pd;
asyncTask(Context context)
{
this.context = context;
pd = new ProgressDialog(activityContext);
}
protected void onPreExecute()
{
pd.setTitle("Loading..");
pd.setMessage("Please wait ...");
pd.setCancelable(false);
pd.show();
}
protected void onPostExecute(Boolean result)
{
if(pd.isShowing()) pd.dismiss();
}
#Override
protected Boolean doInBackground(Void... params)
{
convertvalues();
return boolean_value;
}
}
And Just Call this asynctask with
new asyncTask(Your_Context).execute();
I have developed an Android App that communicates via HTTP-Request with a server.
Some times it takes more time for a request so the app shows just a black screen and passes some seconds later. Sometimes the black screen appears some seconds later and you can send the request again and again.
Is there any possibility to disable the onTouch-Events or show a layer while the screen is loading?
Thank you.
use an asyncTask and launch your httprequest in the doInBackground() method, and for blocking the user , just display a ProgressDialog :
class YourRequestTask extends AsyncTask<Void, Void, JSONObject> {
ProgressDialog progress;
Context context;
public YourRequestTask(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
progress = ProgressDialog.show(context, null,"Please wait...");
}
#Override
protected JSONObject doInBackground(Void... params) {
//do your work here for your http request
}
#Override
protected void onPostExecute(JSONObject result) {
progress.dismiss();
Log.i(TAG, "result is "+result.toString());
}
}