How to set text to a text view from a Thread class - java

I am reading a inputstream chunck by chunk and tryng to set read chunk to a textview from a Thread class but text is only getting printed after completion of while loop below is my code :
class SendFileThread extends Thread
{
Handler mHandler;
FileInputStream instream;
SendFileThread(Handler h, FileInputStream stream )
{
mHandler = h;
instream = stream;
this.setPriority(Thread.MAX_PRIORITY);
}
#Override
public void run()
{
final StringBuilder result = new StringBuilder();
Message msg;
byte [] usbdata = new byte[64];
int readcount = 0;
sendByteCount = 0;
int val = 0;
if(instream != null)
{
try
{
readcount = instream.read(usbdata,0,64);
}
catch (IOException e){e.printStackTrace();}
while(readcount > 0)
{
sendData(readcount, usbdata);
sendByteCount += readcount;
try
{
readcount = instream.read(usbdata,0,64);
if(readcount == -1){
pending = false;
//send_file = false;
setDefaultsBoo("pending",pending, J2xxHyperTerm.this);
}else{
result.append(new String(usbdata, 0, readcount));
}
runOnUiThread(new Runnable() {
#Override
public void run() {
readText.setMovementMethod(new ScrollingMovementMethod());
readText.setText(result.toString());
//scrollView.smoothScrollTo(0, readText.getHeight() + 30);
}
});
}
catch (IOException e){e.printStackTrace();}
}
}
}
}
text is getting set to textview only after all the work is done.

After work is done, try this -
Message msg = Message.obtain(handler, what, arg1, arg2, "text");
// what= some int identififer, lets say 1101
msg.sendToTarget();
in the listening activity implement Handler.Callback. You will have to implement handleMessage
#Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case 1104: // the what identifier you set in message
String text = (String) msg.obj;
textView.setText(text)
break;
}
return false;
}

You could use an AsyncTask for this use-case, as the ability to update views on the UI thread is included right out of the box.
http://developer.android.com/reference/android/os/AsyncTask.html
This is from the usage example provided, with comments to show you where the main thread action happens.
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
// Done in the background, on a separate thread
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
// This part of the loop publishes the progress to onProgressUpdate(..)
publishProgress((int) ((i / (float) count) * 100));
if (isCancelled()) break;
}
return totalSize;
}
// Called on the main thread whenever publishProgress(..) is called
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
// Also called on the main thread, after the background task is finished
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}

Hi you can use this method in your thread :
runOnUiThread(new Runnable() {
#Override
public void run() {
//update your textview
}
});

You could use an EventBus, to communicate between your thread to your activity.
This is their github project. you can implement it and also enable communication between every Android app component. For example, like in your case, between thread and activity.

Related

Unable to update Circular ProgressBar while downloading file

I have used Retrofit2 for file download. I am not able to update ProgressBar with progress value. I got progress value. So there is not issue. When I set the progress value to progress bar not reflected in UI.
I am talking about Progress Bar which is present inside RecyclerView Adapter.
Below is my retrofit call,
And this method will be called when clicking a item inside RecyclerView.
private void downloadFileFromServer(String otpapi, String userName, String password, String code, String vmFileName, String filePath, String vmFileSize, int position, CircularProgressBar circularProgress) {
GetDataForApiCall getDataForApiCall= RetrofitInstance.getRetrofit(url,otpapi,context).create(GetDataForApiCall.class);
Call<ResponseBody> downloadVoicemail= getDataForApiCall.downloadVoiceMail(userName,password,code,vmFileName);
this.circularProgressBar=circularProgress;
this.circularProgressBar.setIndeterminate(false);
this.circularProgressBar.setProgress(0);
this.circularProgressBar.setMax(100);
this.circularProgressBar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AndroidLogger.log(5,"onClick","circularProgressBar onClick executed!!");
Toast.makeText(context,"cancel clicked",Toast.LENGTH_LONG).show();
cancelDownload = true;
}
});
downloadVoicemail.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
boolean downloadResult = writeResponseBodyToDisk(response.body(),vmFileSize,filePath);
if(downloadResult) {
Toast.makeText(context, "File downloaded", Toast.LENGTH_SHORT).show();
updateVoiceMailFilePath(position, filePath);
updateViews(position);
}else {
deleteVoiceMailFileFromLocalSystem(filePath);
updateViews(position);
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
private boolean writeResponseBodyToDisk( ResponseBody body, String fileSize, String filePath) {
try {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[8192];
//long fileSize = body.contentLength();
long fileSizeDownloaded = 0;
long lengthOfFile = Long.parseLong( String.format( "%.0f",Double.parseDouble(fileSize )) ) * 1024;
AndroidLogger.log(5,TAG,"filesize"+fileSize + "length of file"+lengthOfFile);
inputStream = body.byteStream();
outputStream = new FileOutputStream(filePath);
while (true) {
int read = inputStream.read(fileReader);
if(cancelDownload){
inputStream.close();
return false;
}
if (read == -1) {
AndroidLogger.log(5,TAG,"-1 value so break");
break;
}
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
if(lengthOfFile >0) {
AndroidLogger.log(5,TAG,"FileSize downloaded"+ fileSizeDownloaded);
int progress = (int) (fileSizeDownloaded * 100 / lengthOfFile);
AndroidLogger.log(5,TAG,"Length of file"+ lengthOfFile);
AndroidLogger.log(5,TAG,"Progress"+ progress);
this.circularProgressBar.setProgress(progress);
update(progress);
}
AndroidLogger.log(5,TAG, "file download: " + fileSizeDownloaded + " of " + fileSize);
}
outputStream.flush();
return true;
} catch (IOException e) {
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (IOException e) {
return false;
}
}
Also I have tried Listener to update value because retrofit call done on some other thread. So for update UI I have used listener which is not helped.
I am using Retrofit2 for making API calls. So for updating UI in all Activities I had used interface listeners. This works perfect for all Activities. But when I tried the same thing in RecyclerView Adapter class, not able to update progress bar. Before calling api I had set Progress bar to 0 and max to 100.
Below case Works fine,
Circular ProgressBar before API call set to Zero
Circular ProgressBar after download Completed will change to a tick mark
Below is not Working,
Circular ProgressBar with indication of loading
NOTE: I am facing this issue only when used Retrofit2 to make API call. If I used normal HTTPUrlConnection for making API call inside a Asynctask, then progress loading working fine.
I have checked whether the progress updation is occurs on main thread or not by below code,
if(Looper.myLooper() == Looper.getMainLooper()) {
circularProgressBar.setProgress(progress);
}
The above if condition is satisfied. Eventhough Progress bar not updated.
Also I have tried below,
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
#Override
public void run() {
AndroidLogger.log(5,TAG,"Running on UI thread");
circularProgressBar.setProgress(progress);
}
};
mainHandler.post(myRunnable);
}
I have placed this inside writeResponseBodyToDisk method, inside while loop,
But it was called only two times and progress bar not updated.
I commented the part, where the progress bar loading will change to a tick mark. After that when I tried download,once download completed able to see 100 percent download completed in progress bar. Before progress percent updation not reflected.
Please Anybody help me out to solve this issue.
Thanks in advance.
The UI updates are needed to be happened in the UI thread. Setting the color from a background thread (i.e. AsyncTask) will not actually update the UI as this is not happening in the UI thread. There are several ways to update the progress color in the UI. I would recommend having an interface along with a callback function so that you can invoke that callback function to update the UI from the activity of fragment that implemented it. Here's a clarification.
Let us declare an interface first.
public interface UIUpdater {
void updateUI(int progressValue);
}
Now implement this interface in the activity or fragment where you want to update the UI.
public class MainActivity extends Activity implements UIUpdater {
#Override
public void updateUI(int progressValue) {
// Do the UI update here.
circularProgress.setProgress(progressValue); // Or anything else that you want to do.
}
}
You want to modify the constructor of initializing your AsyncTask to have the UIUpdater class to be passed as parameter.
public class YourAsyncTask extends AsyncTask<String, Void, String> {
UIUpdater listener;
public YourAsyncTask(UIUpdater listener) {
this.listener = listener;
}
}
So that you can call the AsyncTask from the activity/fragment using something as following.
YourAsyncTask myTask = new YourAsyncTask(this); // When you are passing this from activity, you are implicitly passing the interface that it implemented.
myTask.execute();
Now from the async task, while you are publishing the progress, invoke the listener function in order to update the UI using the UI thread of your activity/fragment.
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
try {
listener.updateUI(values[0]);
}
}
Hope you get the idea.
Your problem is not that you are using a RecyclerView, your problem is that you're not using it correctly.
It's is neither the adapter, nor the view (RecyclerView) nor even the ViewHolder's responsibility to determine anything here.
I assume you have a ViewHolder type with a progress bar in it.
I assume you have a ListAdapter<T, K> with the corresponding DiffUtilCallback implementation.
I assume progress is handled/reported elsewhere (in your repository, through a viewModel or Presenter, via a useCase, Interactor, or even the plain ViewModel).
Your adapter now has nothing to do but wait.
When progress is updated, you prepare the List you are displaying so the item whose progress has changed is updated.
Afterwards you submit this new list (with the new progress) to your adapter.
Your DiffUtil calculates this (it can be async too!)
Your RecyclerView is magically updated, no need to hack anything.
If any of these is not true, perform the necessary adjustments so your code can be properly tested and the concerns of each piece of code is better separated.
Think about it this way, imagine you had all that, and there was a small bug in the "progress value" you update. Which would be easier, search in the little function in your ViewModel or UseCase/interactor that transforms the Retrofit value into your <Thing>, or all over the place in your spaghetti code of callbacks?
Thank you all for trying to help me!!
This answer helped me to update Circular ProgressBar
https://stackoverflow.com/a/42119419/11630822
public static Retrofit getDownloadRetrofit(String baseUrl, DownloadVoicemailListener listener) {
return new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.client(getOkHttpDownloadClientBuilder(listener).build())
.build();
}
private static OkHttpClient.Builder getOkHttpDownloadClientBuilder(DownloadVoicemailListener listener) {
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder().connectionSpecs(Collections.singletonList(getConnectionSpec()));
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
if (!releaseMode) {
logging.level(HttpLoggingInterceptor.Level.BODY);
httpClientBuilder.addInterceptor(logging);
}
httpClientBuilder.connectTimeout(20, TimeUnit.SECONDS);
httpClientBuilder.writeTimeout(0, TimeUnit.SECONDS);
httpClientBuilder.readTimeout(5, TimeUnit.MINUTES);
httpClientBuilder.addInterceptor(new Interceptor() {
#NotNull
#Override
public Response intercept(#NotNull Interceptor.Chain chain) throws IOException {
if (listener == null) return chain.proceed(chain.request());
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.body(new ProgressResponseBody(originalResponse.body(), listener))
.build();
}
});
return httpClientBuilder;
}
In Progressbody class,
public class ProgressResponseBody extends ResponseBody {
private final String TAG=ProgressResponseBody.class.getSimpleName();
private ResponseBody responseBody;
private BufferedSource bufferedSource;
public ProgressResponseBody(ResponseBody responseBody, DownloadVoicemailListener progressListener) {
this.responseBody = responseBody;
progressListener.readFile(responseBody);
}
#Override public MediaType contentType() {
return responseBody.contentType();
}
#Override public long contentLength() {
return responseBody.contentLength();
}
#NotNull
#Override public BufferedSource source() {
if (bufferedSource == null) {
bufferedSource = Okio.buffer(source(responseBody.source()));
}
return bufferedSource;
}
private Source source(Source source) {
return new ForwardingSource(source) {
long totalBytesRead = 0L;
#Override public long read(Buffer sink, long byteCount) throws IOException {
return byteCount;
}
};
}
}
#Override
public void readFile(ResponseBody responseBody) {
boolean result = writeResponseBodyToDisk(responseBody);
}
private boolean writeResponseBodyToDisk(ResponseBody body) {
try {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
long fileSizeDownloaded = 0;
AndroidLogger.log(5, TAG, "File path" + filePath);
AndroidLogger.log(5, TAG, "File size" + fileSize);
long lengthOfFile = Long.parseLong(String.format("%.0f", Double.parseDouble(this.fileSize))) * 1024;
AndroidLogger.log(5, TAG, "filesize" + fileSize + "length of file" + lengthOfFile);
inputStream = body.byteStream();
outputStream = new FileOutputStream(this.filePath);
byte[] data = new byte[4096];
long total = 0;
int count;
while ((count = inputStream.read(data)) != -1) {
if (cancelDownload) {
AndroidLogger.log(5,TAG,"Cancel download clicked");
inputStream.close();
return false;
}
total += count;
outputStream.write(data, 0, count);
fileSizeDownloaded += count;
if (lengthOfFile > 0) {
AndroidLogger.log(5, TAG, "FileSize downloaded" + fileSizeDownloaded);
int progress = (int) (fileSizeDownloaded * 100 / lengthOfFile);
AndroidLogger.log(5, TAG, "Length of file" + lengthOfFile);
AndroidLogger.log(5, TAG, "Progress" + progress);
((Activity) context).runOnUiThread(new Runnable() {
#Override
public void run() {
circularProgressBar.setProgress(progress);
}
});
}
}
AndroidLogger.log(5, TAG, "file download: " + fileSizeDownloaded + " of " + fileSize);
outputStream.flush();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
}

ArrayList doesn't display value outside of method where the data storing happens

I have this class where it process XML and store it inside an ArrayList<FeedItem>. I can display the array content in the method where I store the data but when I try to display the array in another method it did not pass the if checking indicating that the ArrayList is empty. Because of this, I can't create a ListView because it'll return the same error. I hope someone can briefly explain to me what is wrong.
ReadRSS.java
public class ReadRSS extends AsyncTask<Void, Void, Void> {
//Initialize progress dialog
Context context;
String address;
ProgressDialog progressDialog;
XmlPullParserFactory xmlPullParserFactory;
volatile boolean parsingComplete = true;
ArrayList<FeedItem> feedItems;
ListView listView;
public ReadRSS(Context context, ListView listView, String retrieveAddress) {
//Create a new progress dialog
this.listView = listView;
this.address = retrieveAddress;
this.context = context;
progressDialog = new ProgressDialog(context);
progressDialog.setMessage("Loading....");
}
// Runs in UI before background thread is called
#Override
protected void onPreExecute() {
//Display progress dialog
progressDialog.show();
super.onPreExecute();
}
// This is run in a background thread
#Override
protected Void doInBackground(Void... voids) {
fetchXML();
return null;
}
// This is called from background thread but runs in UI
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
// This runs in UI when background thread finishes
#Override
protected void onPostExecute(Void aVoid) {
//Dismiss progress dialog
super.onPostExecute(aVoid);
progressDialog.dismiss();
/*if(listView != null) {
CustomAdapter customAdapter = new CustomAdapter(context, R.layout.activity_listview, feedItems);
listView.setAdapter(customAdapter);
}*/
if(feedItems != null){
//Gives error
for(int i = 0; i < feedItems.size(); i++) {
Log.d("Title", feedItems.get(i).getTitle());
Log.d("Date", feedItems.get(i).getPubDate());
}
}
}
//New Build
public void parseXMLAndStoreIt(XmlPullParser myParser) {
int event;
String text;
String title = null;
String date = null;
feedItems = new ArrayList<FeedItem>();
try {
event = myParser.getEventType();
while (event != XmlPullParser.END_DOCUMENT) {
String tagName = myParser.getName();
switch (event){
case XmlPullParser.START_TAG:
if(tagName.equalsIgnoreCase("item")){
int eventChild = myParser.next();
//int innerLoop = 1;
String tagNameChild = "";
while(eventChild != XmlPullParser.END_DOCUMENT){
if(eventChild == XmlPullParser.START_TAG){
tagNameChild = myParser.getName();
// Output Test
//Log.d("Tag ", tagNameChild);
}
else if (eventChild == XmlPullParser.TEXT){
text = myParser.getText();
// Output Test
//Log.d("Test ", text);
if(tagNameChild.equalsIgnoreCase("title")){
title = text;
// Output Test
//Log.d("Title ", myParser.getText());
}
else if(tagNameChild.equalsIgnoreCase("pubDate")){
date = text;
// Output Test
//Log.d("PubDate ", myParser.getText());
}
}
else if (eventChild == XmlPullParser.END_TAG){
if(myParser.getName().equalsIgnoreCase("item")){
feedItems.add(new FeedItem(title,date));
// Output Test
//Log.d("Test ", title);
}
tagNameChild = "";
}
eventChild = myParser.next();
//innerLoop++;
}
//Output Test
/*for(int i = 0; i < feedItems.size(); i++) {
Log.d("Title", feedItems.get(i).getTitle());
Log.d("Date", feedItems.get(i).getPubDate());
}*/
}
break;
case XmlPullParser.TEXT:
break;
case XmlPullParser.END_TAG:
break;
}
event = myParser.next();
}
parsingComplete = false;
}
catch (Exception e) {
e.printStackTrace();
}
}
public void fetchXML(){
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
URL url = new URL(address);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 );
conn.setConnectTimeout(15000 );
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
InputStream stream = conn.getInputStream();
xmlPullParserFactory = XmlPullParserFactory.newInstance();
XmlPullParser myparser = xmlPullParserFactory.newPullParser();
myparser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
myparser.setInput(stream, null);
parseXMLAndStoreIt(myparser);
stream.close();
}
catch (Exception e) {
}
}
});
thread.start();
}
}
You are calling fetchXML() from doInBackground, but fetchXML() starts a new thread and then immediately returns. Then doInBackground() immediately returns and onPostExecute() is called. However, at that point, the thread launched by fetchXML() has not had time to finish, so feedItems has not been properly set.
That's the wrong way to use an AsyncTask. Instead, you should do the fetching directly in the doInBackground() thread. Just rewrite fetchXML() to do the fetching itself, rather than launch a separate thread to do the fetching.

Not able to publish progress from async task do in background's while loop - Android

I want to update dialog's download progress from doInBackground.
I am printing log as well as publishing progress.
Neither of them are working.
It updates the dialog in the end and prints all the log values at once in the end
private class DownloadEReport extends AsyncTask<String, Void, Void> {
int progress = 0;
protected void onPreExecute() {
mProgressDialog = new ProgressDialog(EReport.this);
mProgressDialog.setTitle("Downloads");
mProgressDialog.setMessage("Downloading, Please Wait!");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
mProgressDialog.setProgress(progress);
}
#Override
protected Void doInBackground(String... strings) {
String mUrl = strings[0];
String json = "";
int count;
try {
URL url = new URL(mUrl);
URLConnection conection = url.openConnection();
conection.connect();
// getting file length
int lenghtOfFile = conection.getContentLength();
// input stream to read file - with 8k buffer
InputStream input = new BufferedInputStream(url.openStream(), 8192);
// Output stream to write file
OutputStream output = new FileOutputStream("/sdcard/downloadedfile.txt");
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
// writing data to file
output.write(data, 0, count);
// publishing the progress....
// After this onProgressUpdate will be called
Log.e("JSON Download Progress", "" + (int) ((total * 100) / lenghtOfFile));
progress = (int) (total * 100 / lenghtOfFile);
publishProgress();
}
// flushing output
output.flush();
// closing streams
output.close();
input.close();
} catch (Exception e) {
Log.e("Error: ", e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
mProgressDialog.dismiss();
}
}
remove super from onProgressUpdate and then try
#Override
protected void onProgressUpdate(Void... values) {
//super.onProgressUpdate(values);
mProgressDialog.setProgress(progress);
}
if it doesn't work than add a sleep statement in your loop so that this loop will free the processor and give time to publish the progress
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
One possible explanation for the behaviour is that reading from remote input stream and writing it into output buffer is extremely fast.
I tried the same code but with just a loop running for 10 times.
int total = 0;
while(total <= 100){
progress = total;
total += 10;
publishProgress();
}
Even I could not see the progress dialog at first, so put a Thread.sleep() in the loop and the progress dialog works just fine.
int total = 0;
while(total <= 100){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
progress = total;
total += 10;
publishProgress();
}
Try to log the time (System.currentTimeMillis()) at which you are writing into the output buffer.
Hope it helps.

How do I access variables within a Handler? Setting them public did not work

I do not know how to use variables from another handler in a different method. I tried to set those variables(readBuf, readMessage, and msg) as public, but that did not work. How do I access these variables in separate method? I want those variables listed including .arg1 and .obj in another handler.
The code that is commented out is where the processing for the data originally was.
public Handler handler;
public byte[] readBuf;
public String readMessage;
public Object msg;
handler = new Handler();
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1) {
case MESSAGE_READ:
//for(int a = 0; a< 8000; a++)
//{
try
{
byte[] readBuf = (byte[]) msg.obj;
String readMessage = new String(readBuf,0,msg.arg1);
mConversationArrayAdapter.add("Voltage: "+ readMessage);
//double[] convert = new double[1];
//for(int z=0; z <1;z++)
//{
//convert[z]= Double.parseDouble(readMessage);
//}
//for(int j=0; j<1;j++)
//{
//stored[a][j]= convert[j];
//}
//}
catch(NumberFormatException e)
{
System.err.println("NumberFormatException: "+e.getMessage());
}
//}
break;
}
}
};
public void process()
{
new Thread(new Task()).start();
}
class Task implements Runnable
{
#Override
public void run()
{
try{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
handler.post(new Runnable()
{
#Override
public void run(){
for(int a = 0; a< 8000; a++)
{
byte[] readBuf = (byte[]) msg.obj;//ERROR with .obj
try
{
String readMessage = new String(readBuf,0,msg.arg1);// Error with .arg1
mConversationArrayAdapter.add("Voltage: "+ readMessage);
double[] convert = new double[1];
for(int z=0; z <1;z++)
{
convert[z]= Double.parseDouble(readMessage);
}
for(int j=0; j<1;j++)
{
stored[a][j]= convert[j];
}
}
catch(NumberFormatException e)
{
System.err.println("NumberFormatException: "+e.getMessage());
}
}
}
});
}
}
}
The way I used the object variables in other methods was by setting new public static variables equal to the object variables. That way I could use them in other methods.
You must create a Message and send by handler, not "share" variables.
Message msg = new Message();
msg.what = ...;
msg.obj = ...;
....
handler.sendMessage(msg);

adding progress dialog to storefile();

all is it possible to create a progress dialog to show the upload progress under a thread i use this code to upload a file called index.html to ftp.
please help me thanx in advance..
new Thread(new Runnable() {
public void run() {
Looper.prepare();
FTPClient client = new FTPClient();
try {
boolean result = false;
FileInputStream fis = null;
client.connect(server);
client.enterLocalPassiveMode();
client.login(user, pass);
client.makeDirectory("/public_html/"+str);
client.setFileType(FTP.BINARY_FILE_TYPE);
client.setFileTransferMode(FTP.BINARY_FILE_TYPE );
client.changeWorkingDirectory(str);
String path1 = Environment.getExternalStorageDirectory() + "/index.htm";
File f = new File(path1);
String testname = "/public_html/"+str+"/"+f.getName();
fis = new
FileInputStream(f);
result = client.storeFile(testname, fis);
if (result == true){
Log.v("upload","upload successfull");
}
else{
Log.v("upload", "upload failed");
}
client.logout();
client.disconnect();
}
catch (Exception e) {
Context context = getApplicationContext();
CharSequence text = "failed!!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
}
}).start();
Why not use an asynctask? With it you could spawn a dialog in the onPreExecute method than in the onProgressUpdate method update the progress of the background task...There are other ways of doing it but i believe this to be the cleanest and easiest
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
The android dev reference should help clear things up http://developer.android.com/reference/android/os/AsyncTask.html

Categories