2013-08-12 2 views
0

my xml code is;Использование загруженное изображение с сервера в качестве фона ImageView в

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"> 
    <Button 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:text="Click To Download File" 
     android:id="@+id/downloadButton"/> 
    <TextView 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:text="" 
     android:id="@+id/messageText" 
     android:textColor="#000000" 
     android:textStyle="bold" /> 
    <ImageView 
     android:id="@+id/image" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_gravity="center"/> 
</LinearLayout> 

мой класс;

public class DownloadFromServer extends Activity { 

TextView messageText; 
Button downloadButton; 
int serverResponseCode = 0; 
ProgressDialog dialog = null; 
String downloadServerUri = null; 
Drawable drawable; 
final String downloadFileName = "share.png"; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_download_from_server); 

    downloadButton = (Button) findViewById(R.id.downloadButton); 
    messageText = (TextView) findViewById(R.id.messageText); 
    final ImageView image = (ImageView) findViewById(R.id.image); 

    downloadServerUri = "http://www.androidexample.com/media/uploads/"+downloadFileName; 

    downloadButton.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      dialog = ProgressDialog.show(DownloadFromServer.this, "", "Downloading File...",true); 

      new Thread(new Runnable(){ 
       public void run(){ 
        runOnUiThread(new Runnable() { 

         @Override 
         public void run() { 
          messageText.setText("downloading started....");        
         } 
        }); 

        downloadFile(downloadServerUri, downloadFileName); 
        image.setImageDrawable(drawable); 
       } 
      }).start(); 
     } 
    });  
} 
public void downloadFile(String sourceFileUri, String fileName){ 

    try{ 
     File root = android.os.Environment.getExternalStorageDirectory(); 
     File dir = new File (root.getAbsolutePath()); 
     if(dir.exists()==false) { 
      dir.mkdirs(); 
     } 

     URL url = new URL(sourceFileUri); //you can write here any link 
     File file = new File(dir, fileName); 

     long startTime = System.currentTimeMillis(); 
     Log.d("DownloadManager", "download begining"); 
     Log.d("DownloadManager", "download url:" + url); 
     Log.d("DownloadManager", "downloaded file name:" + fileName); 

     URLConnection ucon = url.openConnection(); 
     ucon.setUseCaches(true); 
     drawable = Drawable.createFromStream(ucon.getInputStream(), "image1"); 
     ucon.connect(); 

     InputStream is = ucon.getInputStream(); 
     BufferedInputStream bis = new BufferedInputStream(is); 

     ByteArrayBuffer baf = new ByteArrayBuffer(5000); 
     int current = 0; 
     while ((current = bis.read()) != -1) { 
      baf.append((byte) current); 
     } 

     FileOutputStream fos = new FileOutputStream(file); 
     fos.write(baf.toByteArray()); 
     fos.flush(); 
     fos.close(); 
     Log.d("DownloadManager", "download ready in " + ((System.currentTimeMillis() - startTime)/1000) + " sec"); 
     dialog.dismiss(); 
    } 
    catch (IOException e) { 
      Log.d("DownloadManager", "Error: " + e); 
      dialog.dismiss(); 
    } 

} 

}

i tried to take an uploaded image from server with name share.png, and i want to use that image as my ImageView's background. But, my problem is that, i can not use setImageDrawable() or setBackground() in any thread. The program is failed with that error: "Only the original thread that created a view hierarchy can touch this view." How can i fix that error. Thanks a lot.

ответ

1

Изменить кнопку гр лизать, как показано ниже:

downloadButton.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      dialog = ProgressDialog.show(DownloadFromServer.this, "", "Downloading File...",true); 

      new Thread(new Runnable(){ 
       public void run(){ 
        runOnUiThread(new Runnable() { 

         @Override 
         public void run() { 
          messageText.setText("downloading started....");        
         } 
        }); 

        downloadFile(downloadServerUri, downloadFileName); 
        new Handler(Looper.getMainLooper()).post(new Runnable() { 

         @Override 
         public void run() { 
          image.setImageDrawable(drawable); 
         } 
        }); 

       } 
      }).start(); 
     } 
    }); 

или

downloadButton.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 
      dialog = ProgressDialog.show(DownloadFromServer.this, "", "Downloading File...",true); 

      final Handler handler=new Handler(); 

      new Thread(new Runnable(){ 
       public void run(){ 
        runOnUiThread(new Runnable() { 

         @Override 
         public void run() { 
          messageText.setText("downloading started....");        
         } 
        }); 

        downloadFile(downloadServerUri, downloadFileName); 
        handler.post(new Runnable() { 

         @Override 
         public void run() { 
          image.setImageDrawable(drawable); 
         } 
        }); 

       } 
      }).start(); 
     } 
    }); 

Приведенный выше код будет обновлять вид изображения с Drawable в потоке пользовательского интерфейса, и все будет хорошо ..

+0

спасибо много Бабу, первый работает для меня :) –

0

Вы обновляете/экранным пользовательский интерфейс от фонового потока, которое не возможно. Вы должны обновить/получить доступ к ui в потоке ui.

Переместить его в runOnUiThread

 image.setImageDrawable(drawable); 

Вы также можете использовать AsyncTask, чтобы избежать путаницы.

Используйте onPreExecute и onPostExecute для обновления ui. Загрузите ли вы в doInBackground. Результат вычисления doInBackground является параметром для onPostExecute. Получите результат в onPostExecute и обновите ui.

AsyncTask документы

http://developer.android.com/reference/android/os/AsyncTask.html

Edit:

public class MainActivity extends Activity { 

TextView messageText; 
Button downloadButton; 
int serverResponseCode = 0; 
ProgressDialog dialog = null; 
String downloadServerUri = null; 
Drawable drawable; 
final String downloadFileName = "share.png"; 
ImageView image; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    downloadButton = (Button) findViewById(R.id.downloadButton); 
    messageText = (TextView) findViewById(R.id.messageText); 
    image = (ImageView) findViewById(R.id.image); 

    downloadServerUri = "http://www.androidexample.com/media/uploads/"+downloadFileName; 

    downloadButton.setOnClickListener(new OnClickListener() { 

     @Override 
     public void onClick(View v) { 

      new DownLoadTask().execute(); 
     } 
    });  
} 

class DownLoadTask extends AsyncTask<Void,Void,Void> 
{ 


    @Override 
    protected void onPreExecute() { 
     // TODO Auto-generated method stub 
     super.onPreExecute(); 
     dialog = ProgressDialog.show(MainActivity.this, "", "Downloading File...",true); 
    } 

    @Override 
    protected Void doInBackground(Void... arg0) { 
     downloadFile(downloadServerUri, downloadFileName); 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     // TODO Auto-generated method stub 
     super.onPostExecute(result); 
     dialog.dismiss(); 
     image.setImageDrawable(drawable); 
    } 

} 
public void downloadFile(String sourceFileUri, String fileName){ 

    try{ 
     File root = android.os.Environment.getExternalStorageDirectory(); 
     File dir = new File (root.getAbsolutePath()); 
     if(dir.exists()==false) { 
      dir.mkdirs(); 
     } 

     URL url = new URL(sourceFileUri); //you can write here any link 
     File file = new File(dir, fileName); 

     long startTime = System.currentTimeMillis(); 
     Log.d("DownloadManager", "download begining"); 
     Log.d("DownloadManager", "download url:" + url); 
     Log.d("DownloadManager", "downloaded file name:" + fileName); 

     URLConnection ucon = url.openConnection(); 
     ucon.setUseCaches(true); 
     drawable = Drawable.createFromStream(ucon.getInputStream(), "image1"); 
     ucon.connect(); 

     InputStream is = ucon.getInputStream(); 
     BufferedInputStream bis = new BufferedInputStream(is); 

     ByteArrayBuffer baf = new ByteArrayBuffer(5000); 
     int current = 0; 
     while ((current = bis.read()) != -1) { 
      baf.append((byte) current); 
     } 

     FileOutputStream fos = new FileOutputStream(file); 
     fos.write(baf.toByteArray()); 
     fos.flush(); 
     fos.close(); 
     Log.d("DownloadManager", "download ready in " + ((System.currentTimeMillis() - startTime)/1000) + " sec"); 
     dialog.dismiss(); 
    } 
    catch (IOException e) { 
      Log.d("DownloadManager", "Error: " + e); 
      dialog.dismiss(); 
    } 

} 
} 

SnapShot

enter image description here

+0

я сделать это, но мой вытяжке теперь null, поэтому на экране нет изображения. –

+0

@Droid вы не делаете это правильно, поэтому его нулевое использование asynctask – Raghunandan

+0

Не может ли это быть сделано с помощью метода «ImageOperations» перед 'setImageDrawable' (потому что он использует контекст)? Как второе мнение? – g00dy

0
loadImage(url); 



void loadImage(String image_location) { 

    URL imageURL = null; 
    if (image_location != null) { 
     try { 
      imageURL = new URL(image_location); 
     } 

     catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } 

     try { 
      HttpURLConnection connection = (HttpURLConnection) imageURL 
        .openConnection(); 
      connection.setDoInput(true); 
      connection.connect(); 
      InputStream inputStream = connection.getInputStream(); 

      bitmap = BitmapFactory.decodeStream(inputStream);// Convert to 
                   // bitmap 
      ivdpfirst.setImageBitmap(bitmap); 
     } catch (IOException e) { 

      e.printStackTrace(); 
     } 
    } else { 
     ivdpfirst.setImageDrawable(getResources().getDrawable(
       R.id.ivdpfirst)); 

    } 
} 
Смежные вопросы