我的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()。程序因该错误而失败:“只有创建视图层次结构的原始线程才能触及此视图。” 我该如何解决这个错误。非常感谢。
答案 0 :(得分: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更新图像视图,一切都会很好..
答案 1 :(得分:0)
您正在从后台线程更新/访问ui,这是不可能的。你应该在ui线程上更新/访问ui。
将其移至runOnUiThread
image.setImageDrawable(drawable);
您还可以使用AsyncTask
来避免混淆。
使用onPreExecute
和onPostExecute
更新ui。在doInBackground
下载。 doInBackground
计算的结果是onPostExecute
的参数。接收结果onPostExecute
并更新ui。
AsyncTask docs
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();
}
}
}
快照
答案 2 :(得分: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));
}
}