Reputation: 3971
private class DownloadLargeFileTask extends AsyncTask<Void, Void, Void>
{
private final ProgressDialog dialog;
public DownloadLargeFileTask(ProgressDialog dialog) {
this.dialog = dialog;
}
protected void onPreExecute() {
dialog.show();
}
protected void onPostExecute(Void unused) {
dialog.dismiss();
}
@Override
protected Void doInBackground(Void... arg0) {
download();
return null;
}
}
private void download ()
{
try
{
long startTime = System.currentTimeMillis();
URL u = new URL("http://mds.podfm.ru/188/download/040_Sergejj_Palijj_-_Karantin_CHast_2.mp3");
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File("/sdcard/","my.mp3"));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
int downloadedSize = 0;
while ( (len1 = in.read(buffer)) != -1 )
{
f.write(buffer,0, len1);
downloadedSize += len1;
ReturnDownloadedBytes(downloadedSize);
}
f.close();
Log.d("ImageManager", "download ready in" + ((System.currentTimeMillis() - startTime) / 1000) + " sec");
}
catch (IOException e)
{
Log.d("ImageManager", "Error" + ((System.currentTimeMillis()) / 1000) + e + " sec");
}
}
private void ReturnDownloadedBytes(int size)
{
text.setText(String.valueOf(size));
}
Error says: Only the original thread that created a view hierarchy can touch its views. i think this means that i create textview from one therad and trying to get access from another one (AsyncTask) but how to get it? Thanks
EDIT
here is the all code. but even if i send in publishProgress(downloadedSize) int value = 10
it alwys outputs in text.setText(String.valueOf(progress));
different values like [Ljava.lang.float;@43ed62f78
public class list extends Activity {
private TextView text;
@Override
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
setContentView(R.layout.main);
text = (TextView)findViewById(R.id.result);
}
public void selfDestruct(View view) {
ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("????????. ?????...");
new DownloadLargeFileTask(dialog).execute();
}
private class DownloadLargeFileTask extends AsyncTask<Void, Integer, Void>
{
private final ProgressDialog dialog;
public DownloadLargeFileTask(ProgressDialog dialog) {
this.dialog = dialog;
}
protected void onPreExecute() {
dialog.show();
}
protected void onPostExecute(Void unused) {
dialog.dismiss();
}
protected void onProgressUpdate(Integer...progress) {
text.setText(String.valueOf(progress));
}
@Override
protected Void doInBackground(Void... arg0) {
try
{
long startTime = System.currentTimeMillis();
URL u = new URL("http://mds.podfm.ru/188/download/040_Sergejj_Palijj_-_Karantin_CHast_2.mp3");
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
FileOutputStream f = new FileOutputStream(new File("/sdcard/","my.mp3"));
InputStream in = c.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
int downloadedSize = 10;
while ( (len1 = in.read(buffer)) != -1 )
{
f.write(buffer,0, len1);
//downloadedSize += len1;
**publishProgress(downloadedSize);**
}
f.close();
Log.d("ImageManager", "download ready in" + ((System.currentTimeMillis() - startTime) / 1000) + " sec");
}
catch (IOException e)
{
Log.d("ImageManager", "Error" + ((System.currentTimeMillis()) / 1000) + e + " sec");
}
return null;
}
}
Upvotes: 1
Views: 1942
Reputation: 10918
You are correct in your assessment of the error. I'm assuming that text
is a TextView
object that is defined in your Activity
, and as such it is created in the UI thread. The code that runs within doInBackground()
runs in a separate thread. Only the UI thread can perform updates to UI elements, so when you try to call setText
you get the error message that you reported.
Abhinav is also correct in how to fix the issue, as AsyncTask
has a method that you can call to send updates from the background thread to the UI thread: publishProgress
, which calls onProgressUpdate()
.
Add this method to your AsyncTask
:
@Override
protected void onProgressUpdate(Integer... integer){
text.setText(integer[0].toString());
}
And change the while
loop in download()
:
while ( (len1 = in.read(buffer)) != -1 )
{
f.write(buffer,0, len1);
downloadedSize += len1;
publishProgress(downloadedSize);
}
Upvotes: 2
Reputation: 39942
You can change the UI by publishing the progress to the UI thread. Call publishProgress from doInBackground. This will call onProgressUpdate in your AsyncTask from where you can update the UI.
You will have to define onProgressUpdate in your AsyncTask. http://developer.android.com/reference/android/os/AsyncTask.html#onProgressUpdate(Progress...)
Upvotes: 2