【问题标题】:Having issues with Drawable objectsDrawable 对象有问题
【发布时间】:2014-03-24 02:14:53
【问题描述】:

我遇到了这个应用程序的问题,应该很容易解决,但我就是不知道我到底做错了什么......该应用程序所做的只是在一个线程中下载图像并设置另一个线程中的图像。我更改了 ReadFile 类以将 Drawable 对象返回到变量 finalImage 中,然后我有 onPostExecute 将该图像设置为 ImageView 但是......它唯一显示的是一个 Android 图标。任何建议,将不胜感激。我猜这与我从 ReadFile 类返回 Drawable 的方式有关,但我无法弄清楚究竟是什么。

package com.example.imageviewer;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.widget.ImageView;

public class MainActivity extends Activity {

    private final String URL_STRING = "http://cdn.theatlantic.com/static/infocus/putin091311/s_p15_0RTXUL0R.jpg";
    private final String FILENAME = "s_p15_0RTXUL0R.jpg";
    private ImageView fileImageView; 
    public Drawable finalImage;

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

        fileImageView = (ImageView) findViewById(R.id.fileImageView);

        new DownloadFile().execute();
        new ReadFile().execute();

    }

    class DownloadFile extends AsyncTask<Void, Void, String> {
        @Override
        protected String doInBackground(Void... params) {
            // download and write the file
            try{
                // get the URL object
                URL url = new URL(URL_STRING);

                // get the input stream
                InputStream in = url.openStream();

                // get the output stream
                FileOutputStream out = 
                        openFileOutput(FILENAME, Context.MODE_PRIVATE);

                // read input and write output
                byte[] buffer = new byte[1024];
                int bytesRead = in.read(buffer);
                while (bytesRead != -1)
                {
                    out.write(buffer, 0, bytesRead);
                    bytesRead = in.read(buffer);
                }
                out.close();
                in.close();

                // return a message
                return "File downloaded";
            }
            catch (IOException e) {
                return "Error: " + e.toString();
            }
        }

        @Override
        protected void onPostExecute(String message) {
            Log.d("Test", message);

            fileImageView.setImageDrawable(finalImage);

        }                
    }

        public class ReadFile extends AsyncTask <Void, Void, Drawable>{

            @Override
            protected Drawable doInBackground(Void...params){
                try {
                    FileInputStream in = openFileInput(FILENAME);
                    Drawable image = Drawable.createFromStream(in, FILENAME);
                    fileImageView.setImageDrawable(image);
                    Log.d("Test", "File read");            
                } 
                catch (Exception e) {
                    Log.e("Test", "Error: " + e.toString());
                }
                return finalImage;
            }

        }

}

【问题讨论】:

    标签: java android multithreading asynchronous drawable


    【解决方案1】:

    你的问题在这里:

    new DownloadFile().execute();
    new ReadFile().execute();
    

    由于这些是异步任务,它们同时运行,ReadFile 试图在DownloadFile 完成之前打开您的图像文件。

    您只需将new ReadFile().execute(); 移动到DownloadFileonPostExecute() 方法即可。

    然后将以下内容添加到ReadFile,以使 ImageView 刷新:

    @Override
        protected void onPostExecute(Drawable nada) {
            fileImageView.invalidate();
        }
    

    我进行了测试以确保这就是我们所需要的一切,并得到了一张普京和一条狗的照片。

    【讨论】:

    • 谢谢,我试过了,但它似乎仍然无法正常工作。我只是得到一个白屏。所以现在我的 onPostExecute 看起来像这样,它在 DownloadFile 方法中。 @Override protected void onPostExecute(String message) { new ReadFile().execute(); Log.d("测试", 消息); fileImageView.setImageDrawable(finalImage); }
    • 我的错,我忘了提到你需要在你的 ImageView 上调用invalidate()。我已将更正添加到答案中。
    • 你也可以去掉里面有finalImage的三行;他们什么也没做。
    • 谢谢老哥,解决了。我永远不会想到我需要调用 invalidate() ...
    • 没有汗水!很高兴能提供帮助。
    【解决方案2】:

    您应该从 ReadFile 任务返回“image”而不是“finalImage”。

    另外,你可以试试这个而不是 onPostExecute:

    public class MainActivity extends Activity implements AsyncResponse {
        ...
    
        void processFinish(Drawable output) {
            fileImageView.setImageDrawable(finalImage);
        }
    }
    

    AsyncResponse.java:

    public interface AsyncResponse {
        void processFinish(Drawable output);
    }
    

    ReadFile.java:

            public class ReadFile extends AsyncTask <Void, Void, Drawable>{
    
                @Override
                protected Drawable doInBackground(Void...params){
                    Drawable image;
                    try {
                        FileInputStream in = openFileInput(FILENAME);
                        image = Drawable.createFromStream(in, FILENAME);
                        Log.d("Test", "File read");            
                    } 
                    catch (Exception e) {
                        Log.e("Test", "Error: " + e.toString());
                    }
                    return image;
                }
    
    
    
        @Override
        protected void onPostExecute(Drawable result) {
            delegate.processFinish(result);
        } 
    }
    

    【讨论】:

    • 我试图只返回图像,但它只是说没有设置变量,即使我在方法中设置了它...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-20
    • 2017-08-09
    • 1970-01-01
    • 2011-08-05
    相关资源
    最近更新 更多