I've developed an application that takes content from the internet and shows it accordingly on the device's screen . The program works just fine , a little bit slow . It takes about 3-4 seconds to load and display the content . I would like to put my code that does all the work ( grabbing web content and displaying it) in a background thread . Also , I'd like to show a progress dialog .
public class Activity1 extends Activity
{
private ProgressDialog progressDialog;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new AsyncTask<Integer, Integer, Boolean>()
{
ProgressDialog progressDialog;
#Override
protected void onPreExecute()
{
/*
* This is executed on UI thread before doInBackground(). It is
* the perfect place to show the progress dialog.
*/
progressDialog = ProgressDialog.show(Activity1.this, "",
"Loading...");
}
#Override
protected Boolean doInBackground(Integer... params)
{
if (params == null)
{
return false;
}
try
{
/*
* This is run on a background thread, so we can sleep here
* or do whatever we want without blocking UI thread. A more
* advanced use would download chunks of fixed size and call
* publishProgress();
*/
Thread.sleep(params[0]);
// HERE I'VE PUT ALL THE FUNCTIONS THAT WORK FOR ME
}
catch (Exception e)
{
Log.e("tag", e.getMessage());
/*
* The task failed
*/
return false;
}
/*
* The task succeeded
*/
return true;
}
#Override
protected void onPostExecute(Boolean result)
{
progressDialog.dismiss();
/*
* Update here your view objects with content from download. It
* is save to dismiss dialogs, update views, etc., since we are
* working on UI thread.
*/
AlertDialog.Builder b = new AlertDialog.Builder(Activity1.this);
b.setTitle(android.R.string.dialog_alert_title);
if (result)
{
b.setMessage("Download succeeded");
}
else
{
b.setMessage("Download failed");
}
b.setPositiveButton(getString(android.R.string.ok),
new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dlg, int arg1)
{
dlg.dismiss();
}
});
b.create().show();
}
}.execute(2000);
/* new Thread()
{
#Override
public void run()
{
// dismiss the progressdialog
progressDialog.dismiss();
}
}.start();
}*/
}
If I run the application with this code , I get this : download failed . On the other hand , if I keep the final thread , the app crashes , NullPointerException . I really don't know what to do anymore .
I would really appreaciate if you could give me an alternative to this code , not just some hints because I'm new to android and I really don't know much . Thanks.
UPDATE :
I don't want to display the progress of the download , I want to display the progress dialog until the app is ready to display the full content.
The best approach to do this is by using the AsyncTask class, as it will allow you to execute some background process and update the UI at the same time (in your case, it's a progress bar).
This is an example code:
ProgressDialog mProgressDialog = new ProgressDialog(YourActivity.this);
mProgressDialog.setMessage("A message");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
DownloadFile downloadFile = new DownloadFile();
downloadFile.execute("the url to the file you want to download");
The AsyncTask will look like this:
private class DownloadFile extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... url) {
int count;
try {
URL url = new URL(url[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
// this will be useful so that you can show a tipical 0-100% progress bar
int lenghtOfFile = conexion.getContentLength();
// downlod the file
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream("/sdcard/somewhere/nameofthefile.ext");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
publishProgress((int)(total*100/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
The method above (doInBackground) runs always on a background thread. You shouldn't do any UI tasks there. On the other hand, the onProgressUpdate runs on the UI thread, so there you will change the progress bar:
#Override
public void onProgressUpdate(String... args){
// here you will have to update the progressbar
// with something like
mProgressDialog.setProgress(args[0]);
}
}
You will also want to override the onPostExecute method if you want to execute some code once the file has been downloaded completely.
You should create an inner class for AsyncTask like this :
private class YourTask extends AsyncTask<Context, Void, Void>
{
ProgressDialog dialog = new ProgressDialog(mContext);
protected void onPreExecute()
{
dialog.setMessage("loading..");
dialog.show();
}
protected Void doInBackground(Context... params)
{
// ...
return null;
}
protected void onPostExecute(final Void unused)
{
dialog.dismiss();
}
}
and in onCreate() put :
new YourTask().execute();
and for more detail you should check this once:
http://developer.android.com/reference/android/os/AsyncTask.html
When you use the new thread, your app crashes because the progress dialog is not initialized there
Inside your new thread use:
`progressDialog = ProgressDialog.show(Activity1.this, "","Loading...");
and about that alert dialog: Basically either params is null or the logic is throwing some exception. It's not returning true
so check the ddms logs and post them here.
`
Related
I understand that network tasks should be done in an Async thread, and I think my code is inside one, but I still get the error
.MainActivity}: android.os.NetworkOnMainThreadException
which confuses me, since pretty much everything is inside an Async task:
public void onStart() {
super.onStart();
new GetRssFeedTask().execute();
}
The rest of the code is inside the Async task:
private class GetRssFeedTask extends AsyncTask<Void, Void, List<String>> {
private String getRssFeed() throws IOException {
InputStream in = null;
String rssFeed = null;
try {
URL url = new URL("http://stuffilikenet.wordpress.com/feed/main.xml");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
in = conn.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
for (int count; (count = in.read(buffer)) != -1; ) {
out.write(buffer, 0, count);
}
byte[] response = out.toByteArray();
rssFeed = new String(response, "UTF-8");
} finally {
if (in != null) {
in.close();
}
}
return rssFeed;
}
...rest of code (seriously)...
}
Where should I look for my error?
network tasks should be done in an doInBackground() .
doInBackground() callback method runs in a pool of background
threads. To update your UI, you should implement onPostExecute(),
which delivers the result from doInBackground() and runs in the UI
thread, so you can safely update your UI.
perform initilization in onPreExecute() method
perform background task in doInBackground() method
update the UI in onPostExecute() method
public class MyAyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
//Here you can show progress bar or something on the similar lines.
//Since you are in a UI thread here.
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
// Here you are in the worker thread and you are not allowed to access UI thread from here
//Here you can perform network operations or any heavy operations you want.
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
//After completing execution of given task , control will return here.
//Hence if you want to populate UI elements with fetched data, do it here
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
// You can track you progress update here
}
}
It is not enough to do define the network operations inside your AsyncTask class to run them on a background Thread.
You have to execute them inside doInBackgrund().
You need to override doInBackground() inside your AsyncTask class and perform your network operations there.
#Override
protected Void doInBackground(Void... params) {
// here
return null;
}
I have an Android App and I want to download a big file.
REST API implementation is made with AndroidAnnotations. I need to show a progressbar with the download of a big file using this REST Client (made by AndroidAnnotations).
How I to do that?
Regards
Hello Its to late for answering this question but this will be helpful who are still finding ans with Android-annotation
You can check your image progress by little bit manipulation of code and here is what i have created my
Custom converter Class:-
public class CustomConverter extends FormHttpMessageConverter {
OnProgressListener mOnProgressListener;
public CustomConverter() {
super();
List<HttpMessageConverter<?>> partConverters = new ArrayList<HttpMessageConverter<?>>();
partConverters.add(new ByteArrayHttpMessageConverter());
StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
stringHttpMessageConverter.setWriteAcceptCharset(false);
partConverters.add(stringHttpMessageConverter);
partConverters.add(new ProgressResourceHttpMessageConverter());
setPartConverters(partConverters);
}
// public ProgressFormHttpMessageConverter setOnProgressListener(OnProgressListener listener) {
// mOnProgressListener = listener;
// return this;
// }
class ProgressResourceHttpMessageConverter extends ResourceHttpMessageConverter {
#Override
protected void writeInternal(Resource resource, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
InputStream inputStream = resource.getInputStream();
OutputStream outputStream = outputMessage.getBody();
byte[] buffer = new byte[2048];
long contentLength = resource.contentLength();
int byteCount = 0;
int bytesRead = -1;
Log.d("<3 <3 <3", "called");
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
byteCount += bytesRead;
Log.d("<3 <3 <3 ** ", "progress" + String.valueOf((byteCount * 100) / contentLength));
if(mOnProgressListener != null) {
mOnProgressListener.onProgress(resource, byteCount, (int) contentLength);
}
}
outputStream.flush();
}
}
public interface OnProgressListener {
void onProgress(Resource resource, int downloaded, int downloadSize);
}
}
--> you can check your progress with log :)
Code Usage
-> Your rest class will be as follow:-
#Rest(rootUrl = CommonUtils.BASE_URL, converters = {ByteArrayHttpMessageConverter.class,
CustomConverter.class, StringHttpMessageConverter.class})
public interface CustomRest extends RestClientErrorHandling {
#Post(pUrlSignUp)
String _SignUp(MultiValueMap<String, Object> multiValueMap);
}
Of course, you will have to use AsyncTask for downloading purpose:
You can use its methods onPreExecute and onPostExecute for showing and dismissing the ProgressDialog respectively.
Example:
public class DownloadTask extends AsyncTask<String, Integer, String>
{
ProgressDialog pDialog;
Activity activity; //pass your activity reference while initialize this.
public DownloadTask (Activity activity){
this.activity = activity;
}
#Override
protected void onPreExecute()
{
pDialog = new ProgressDialog(activity);
pDialog.setMessage("Downloading file...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... args)
{
//download file's code here
}
#Override
protected void onPostExecute(String result)
{
pDialog.dismiss();
}
}
Hope this helps.
> use AsyncTask method "on progressupdate " to show progress
public class download extends Activity {
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private Button startBtn;
private ProgressDialog mProgressDialog;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startBtn = (Button)findViewById(R.id.startBtn);
startBtn.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
startDownload();
}
});
}
private void startDownload() {
String url = "http://farm1.static.flickr.com/114/298125983_0e4bf66782_b.jpg";
new DownloadFileAsync().execute(url);
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_DOWNLOAD_PROGRESS:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Downloading file..");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}
class DownloadFileAsync extends AsyncTask {
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
#Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream("/sdcard/some_photo_from_gdansk_poland.jpg");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC",progress[0]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
}
}
}
With AndroidAnnotations, you can use background threads and publishing progress easily:
#EActivity
public class MyActivity extends Activity {
public void onCreate(Bundle icicle) {
super.onCreate(icicle)
doSomeStuffInBackground();
}
#Background
void doSomeStuffInBackground() { // will run on a background thread
publishProgress(0);
// Do some stuff
publishProgress(10);
// Do some stuff
publishProgress(100);
}
#UiThread
void publishProgress(int progress) { // will run on the UI thread
// Update progress views
}
}
Now you can only have to figure out how you can get progress events. This answer can give a great inspiration. Unfortunetaly AFAIK there is no built-in callback for that in Spring Android Rest Template.
I was looking to solve this same problem, its being two months now. Finally found a good example, I cant believe everybody copy paste the same in AndroidAnnotations docs, if that were enough, we wouldnt be here seeking for help.
Here is the link where you can see the example
I made some modifications my self, for the moment its working with some toasts, but I hope to comeback with an actual loading animation to share:
/*This background handles my main thread in UI and the progress publish*/
#Background
void thisGETJSON() {
publishProgress(0);
publishProgress(50);
publishProgress(100);
showJSONInUI();
}
/*Here the progress is published and the main UI thread is also called*/
#UiThread
void publishProgress(int progress) {
if (progress == 0) {
Toast toast = Toast.makeText(getApplicationContext(), "Just a sec please", Toast.LENGTH_SHORT);
toast.show();
} else if (progress == 50) {
Toast toast = Toast.makeText(getApplicationContext(), "Loading", Toast.LENGTH_SHORT);
toast.show();
} else if (progress == 100) {
Toast toast = Toast.makeText(getApplicationContext(), "Thanks for waiting", Toast.LENGTH_SHORT);
toast.show();
}
/*This is the main UI thread here I do cool stuff with the JSON objects*/
#UiThread
Void showJSONInUI(); {
//Here I do something with the objects in the JSON
}
This is my download class in which I used Asynctask.Everything works fine, when the file is downloaded fully,it shows 'file downloaded' and on 'ok' press goes back to previous activity.Now I wanted to cancel the asynctask(pls not that 'cancel asynctask' and not only the 'loading' dialogue)on back button press and go back to previous activity.How to do that?someone please help.Thanks in advance
public class Download extends Activity {
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private ProgressDialog mProgressDialog;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.down);
startDownload();
}
private void startDownload() {
String url = data.proj;
new DownloadFileAsync().execute(url);
}
private void showMsg() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Document is downloaded")
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int id) {
//do things
Download.this.finish();
}
});
AlertDialog alert = builder.create();
alert.show();
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_DOWNLOAD_PROGRESS:
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Downloading file..");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}
class DownloadFileAsync extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
#Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
Log.d("ANDRO_ASYNC", "Lenght of file: " + lenghtOfFile);
String fname;
fname = data.proj.substring( data.proj.lastIndexOf('/')+1, data.proj.length() );
InputStream input = new BufferedInputStream(url.openStream());
String path=Environment.getExternalStorageDirectory()
.toString() + File.separator;
OutputStream output = new FileOutputStream(path+fname);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lenghtOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;
}
#Override
protected void onProgressUpdate(String... progress) {
Log.d("ANDRO_ASYNC",progress[0]);
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
showMsg();
}
}}
Really old question, but it seems many people still face an issue in cancelling AsyncTasks. So, here goes...
You will need a field in your AsyncTask class (DownloadFileAsync) to store the View which is being used to cancel the task (a ProgressDialog here).
For ProgressDialog, when creating the dialog, pass true to setCancelable()
mProgressDialog.setCancelable(true);
To pass the view, change the call to the Task as follows:
new DownloadFileAsync(mProgressDialog).execute(url);
and inside our AsyncTask class, create a constructor which saves this value to a field and register an OnCancelListener to call cancel method of AsyncTask:
ProgressDialog mProgressDialog;
DownloadFileAsync(ProgressDialog progressDialog) {
mProgressDialog = progressDialog;
mprogressDialog.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
cancel(true);
}
});
}
In your while loop in doInBackground, add the following code inside the loop:
if (isCancelled()) {
outputStream.flush();
outputStream.close();
inputStream.close();
return null;
}
This way we are checking whether the task was cancelled, every once in a while, and if yes, we close open streams and stop running the task with return (return will be of type given for result of Task). Next, in onCancelled
#Override
protected void onCancelled (Integer fileSize) {
super.onCancelled(fileSize);
Log.d("TASK TAG", "Cancelled.");
//anything else you want to do after the task was cancelled, maybe delete the incomplete download.
}
this is how i did
public class downloadAllFeeds extends AsyncTask<Void, Void, Void>
implements OnCancelListener{
protected void onPreExecute() {
pDialog2.setCancelable(true);
pDialog2.setOnCancelListener(this);
}
#Override
public void onCancel(DialogInterface dialog) {
// TODO Auto-generated method stub
downloadAllFeeds.this.cancel(true);
Log.d("on click cancel true","true");
}
#Override
protected Void doInBackground(Void... params) {
if(isCancelled()==true){
//cancel true stop async
Log.d("cancel true","true");
}else{
//perform your task
}
}
this worked for me, i know this is very old question but it didnt have a answer so i thought i should share what i just now could implement :)
I have an asynctask that is in its own activity. I pass it a string value and it connects to my web service and downloads Json data based on the name I pass in, returning the Json resultset. Works great.
I'd like to add a progress spinner to the asynctask, but I'm stymied as to how to do it. I've perused this and many other blogs, and come close but have not yet found the solution. It seems I either need to have the asynctask in with an Activity class to get the context or I have to pass in the context as a parameter -- but I need the input parameter to be String. I've read about the possibility of building an Object that could hold the String and a Context parameter, but I'm very new to Java and don't know how to build something like that nor have I found a good explanation of how to do so. So often an explanation gets right up to what I need and then says, "... and then you do X and that's it," when X is what I need to know.
All I want is just a spinner thingie to whirl while the download happens. No text, no dialog, just a spinner.
class MyTask extends AsyncTask<Request, Void, Result> {
protected ProgressDialog progressDialog;
#Override
protected void onPreExecute()
{
super.onPreExecute();
progressDialog = ProgressDialog.show(YourActivity.this, "", "", true, false);
}
#Override protected Boolean doInBackground(Request... params) {
// do some work here
return true;
}
#Override protected void onPostExecute(Result res) {
progressDialog.dismiss();
}
}
Add a ProgressBar(this is what it's actually called, Spinners are like drop down menus in Android) to the layout of the Activity where you're initializing your AsyncTask.
Then make two functions startProgress() and stopProgress(), which start and stop the progress bar.
Give your AsyncTask a reference to the Activity, either by sending it during initialization or execution, or making a function in your asyncTask setActivity(MyActivity activity) and call it between your AsyncTask initialization and execution.
Override the onPreExecute() of your AsyncTask to call activity.startProgress() and onPostExecute() to call activity.stopProgress().
EDIT: You can also try passing a reference to the ProgressBar in the constructor of your AsyncTask. Get the reference to the ProgressBar in the onCreate() method of your activity, then add it in the AsyncTask constructor. In the onPreExecute() and onPostExecute() methods of the AsyncTask, start and stop the progress bars accordingly.
You can pass various parameters to an AsyncTask, not just one!
One way to do this is to make member variables in your AsyncTask and initialize them using a constructor that accepts parameters.
For example:
private class MyAsyncTask extends AsyncTask<null, null, null> {
String mFirstParam = null;
Context mContext = null;
// Constructor which accepts parameters
public MyAsyncTask(String _firstParam, Context _context){
this.mFirstParam = _firstParam;
this.mContext = _context;
}
}
When you create an instance of your AsyncTask, create it as follows:
MyAsyncTask task = new MyAsyncTask(myFirstStringParam, mySecondContextParam);
task.execute();
Now you can use both these parameters throughout the scope of your AsyncTask.
Consider passing the ImageView containing of "loading" image and set its Visibility to View.GONE once you have finished downloading your data.
i.e. download your data in the doInBackground method and then change the ImageViews visibility to View.GONE in the onPostExecute method
I think you can pass the progress bar instance to AsyncTask when your create it in its constructor. Here is a downloader example by using AsyncTask -
public void downloadFile(String url, String path, ProgressDialog progress) {
DownloadFileAsync downloader = new DownloadFileAsync(progress);
File file = new File(path);
if (file.exists()) {
file.delete();
}
downloader.execute(url, path);
}
class DownloadFileAsync extends AsyncTask<String, String, String> {
private final WeakReference<ProgressDialog> progressbarReference;
public DownloadFileAsync(ProgressDialog progress) {
progressbarReference = new WeakReference<ProgressDialog>(progress);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... aurl) {
int count;
try {
URL url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
int lenghtOfFile = conexion.getContentLength();
/*
* android.util.Log.v("downloadFile", "Lenght of file: " +
* lenghtOfFile + ":" + aurl[1]);
*/
InputStream input = new BufferedInputStream(url.openStream());
OutputStream output = new FileOutputStream(aurl[1]);
try {
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""
+ (int) ((total * 100) / lenghtOfFile));
output.write(data, 0, count);
}
} finally {
if (output != null) {
output.flush();
output.close();
}
if (input != null) {
input.close();
}
}
} catch (Exception e) {
ProgressDialog p = null;
if (progressbarReference != null) {
p = progressbarReference.get();
}
if (p != null && p.isShowing()) {
p.dismiss();
}
}
return null;
}
protected void onProgressUpdate(String... progress) {
if (progressbarReference != null) {
ProgressDialog p = progressbarReference.get();
if (p != null) {
p.setProgress(Integer.parseInt(progress[0]));
}
}
}
#Override
protected void onPostExecute(String unused) {
ProgressDialog p = null;
if (progressbarReference != null) {
p = progressbarReference.get();
}
if (p != null && p.isShowing()) {
p.dismiss();
}
}
}
ProgressDialog is a custom Dialog which have a progress bar inside it.
Hope it helps.
I have an Activity, which starts an AsyncTask with an Implemented process dialog. That works fine! But i want to get a String return when the asyncTask has finished. So i have to return something in the onPostExecute - Method.
That result(string) i want to grab in the Activity, which started the AsyncTask.
I do not want to use .get() because it blocks the UI thread.
What do i have to write into onPostExecute and the Activity grab the string from doInBackground?
Thank you for any kind of help to solve this problem ;)
Now with Code:
class BgDL extends AsyncTask<String, Integer, String> {
String finishString="";
private Context context;
ProgressDialog pdialog;
public BgDL(Context cxt) { //get the context (usually "this" from Activity / otherwise progressdialog wont show up!
context = cxt;
pdialog = new ProgressDialog(context);
}
#Override
protected String doInBackground(String... strings) {
OutputStream output;
ByteArrayOutputStream baos = null;
try {
URL url = new URL(strings[0]);
URLConnection connection = url.openConnection();
connection.connect();
int fileLength = connection.getContentLength();
InputStream input = new BufferedInputStream(url.openStream());
if (strings[1]=="toString") { // write byte to string if a file is not given
baos= new ByteArrayOutputStream();
output = new DataOutputStream(baos);
} else { //otherwise to string
output = new FileOutputStream(strings[1]);
}
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress((int) (total * 100 / fileLength));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
if (strings[1]=="toString") {
finishString = baos.toString(); //
} // only write byte to string if a file is not given
} catch (Exception e) {log.d("ex",e.toString());
}
return finishString;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
pdialog.setTitle("Please wait");
pdialog.setIndeterminate(false);
pdialog.setMax(100);
pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pdialog.show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
pdialog.setProgress(progress[0]);
}
protected void onPostExecute(String...finishString) {
pdialog.dismiss();//!!!!!!!!!finishString i want to pass over to my Activity, which started this asynctask with .execute();
}
Create a class in your project which extends activity as shown below:
public class SomeClass extends Activity
{
public void dataFromPostExecute(String data)
{
System.out.println("in mainactivity");
}
}
If you want a single thread for every activity, just create a class which extends
Application
public class Async extends Application
{
private Socket globalSocket;
#Override
public void onCreate()
{
//socket = null;
}
public Socket getglobalSocket()
{
return globalSocket;
}
public void setGlobalSocket(Socket globalSocket)
{
this.globalSocket = globalSocket;
}
}
In your socket class which extends Asynctask do the following:
public SocketClass extends AsyncTask<String,String,String>
{
Async app;
private SomeClass t_act;
public SocketClass(SomeClass sct)
{
t_act = sct;
this.con = tst;
app= ((Async)sct.getApplicationContext());
}
protected void onPostExecute(String data)
{
t_act.dataFromPostExecute(data);
}
}
Then, in your activity extend SomeClass and do as shown below:
public class Activity1 extends SomeClass
{
public void dataFromPostExecute(String data)
{
//do whatever you want. "data" of this method contains the values from
postexecute()
}
}
Your return value from doInBackground() is you formal in onPostExecute().
So you should just be able to pass it in.
What do i have to write into onPostExecute and the Activity grab the
string from doInBackground?
When you are using AsyncTask then you can update your UI only on onProgressUpdate and onPostExecute method.
Your doInBackground() method returns some data and these data is going to onPostExecute method(it depends also how your generic are declared).
Generally, there is no another approaches how to do it.
You meant this:
AsyncTask a = new AsyncTask(Context);
a.execute(Input);
First means that your constructor looks like
public MyAsync(Context c) {
this.c = c;
}
Second means that you declared your first generic type(assumption Input param is String) as
private class MyAsync extends AsyncTask<String, Void, String> {
//...
}
And you want to update UI with String that returns doInBackground() method and merely place is onPostExecute method with IN parameter String that returns doInBackground().
protected void onPostExecute(String stringReturnedFromDoInBackground)
{
// some work
}
So if you want to do it in different way, change your application logic and use for example ResultReceiver with IntentService.