0

我的 xml 代码是;

<?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();
    }

}

}

我试图从名为 share.png 的服务器获取上传的图像,并且我想使用该图像作为我的 ImageView 的背景。但是,我的问题是,我不能在任何线程中使用 setImageDrawable() 或 setBackground() 。该程序因该错误而失败:“只有创建视图层次结构的原始线程才能接触此视图。” 我该如何解决该错误。非常感谢。

4

3 回答 3

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();
        }
    });

上面的代码将使用 UI 线程中的 drawable 更新图像视图,一切都会好起来的。

于 2013-08-12T13:10:06.993 回答
0

您正在从后台线程更新/访问 ui,这是不可能的。您应该在 ui 线程上更新/访问 ui。

移到里面runOnUiThread

      image.setImageDrawable(drawable);

您也可以使用AsyncTask以避免混淆。

使用onPreExecuteonPostExecute更新 ui。做你的下载doInBackground。计算结果doInBackground为参数onPostExecute。接收结果onPostExecute并更新 ui。

AsyncTask 文档

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

编辑:

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();
    }

}
}

快照

在此处输入图像描述

于 2013-08-12T13:07:02.993 回答
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));

    }
}
于 2013-08-12T13:07:18.980 回答