2017-10-07 64 views
2

当用户单击此按钮时,应用程序应从网络中检索图像。它应该在一个单独的线程中执行此操作,并且当图像下载时,它应该使用ImageView显示在同一屏幕上。我似乎无法使其工作,但我觉得我真的很亲密,任何人都可以帮助我?谢谢!输入的图像URL在图像上的editText上查看

我的清单文件

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.example.stephen.asyncdownloadimageurl"> 
<uses-permission android:name="android.permission.INTERNET"> 
</uses-permission> 

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:roundIcon="@mipmap/ic_launcher_round" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 
    <activity android:name=".MainActivity"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 

我的XML文件

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
android:orientation="vertical" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent"> 

<ImageView 
    android:id="@+id/imageView" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    app:srcCompat="@android:drawable/alert_light_frame" 
    android:layout_marginBottom="146dp" 
    android:layout_alignParentBottom="true" 
    android:layout_centerHorizontal="true" /> 

<Button 
    android:id="@+id/button" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_above="@+id/imageView" 
    android:layout_centerHorizontal="true" 
    android:layout_marginBottom="91dp" /> 

<EditText 
    android:id="@+id/editText" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_above="@+id/button" 
    android:layout_centerHorizontal="true" 
    android:layout_marginBottom="51dp" 
    android:ems="10" /> 

我java的文件

public class MainActivity extends AppCompatActivity { 
Button btn; 
EditText et; 

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

    btn = (Button) findViewById(R.id.button); 
    et = (EditText) findViewById(R.id.editText); 

    btn.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 
      try { 
       URL url = new URL(et.getText().toString()); 
       new MyDownloadTask().execute(url); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 
} 

private class MyDownloadTask extends AsyncTask<URL, Integer, Bitmap> { 
    @Override 
    protected Bitmap doInBackground(URL... params) { 
     URL url = params[0]; 
     Bitmap bitmap = null; 
     try { 
      URLConnection connection = url.openConnection(); 
      connection.connect(); 
      InputStream is = connection.getInputStream(); 
      BufferedInputStream bis = new BufferedInputStream(is); 
      bitmap = BitmapFactory.decodeStream(bis); 
      bis.close(); 
      is.close(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return null; 
     } 

     return bitmap; 
    } 

    @Override 
    protected void onPostExecute(Bitmap bitmap) { 
     if (bitmap != null) { 
      ImageView myImage = (ImageView) findViewById(R.id.imageView); 
      myImage.setImageBitmap(bitmap); 
     } else { 
      Toast.makeText(getApplicationContext(), "Failed to Download Image", Toast.LENGTH_LONG).show(); 
     } 
    } 
} 

}

+1

你能描述错误吗?没有结果?没有来自流的数据?有关该问题的更多信息? –

+0

@TannerSummers我的Toast消息无法告诉我它尝试检索图像失败,但它没有得到图像。我所有的代码都运行了,但我似乎无法找到问题atm为什么它是不工作。 –

+0

我把你的代码放到我的电脑里。并且工作正常,除了我没有把st.getText()函数转换成字符串。所以你可能想看看它是否有价值。另外如果我可能会问,为什么你从textview中读取? –

回答

2

使用特殊的android库(如GlidePicasso)来加载图像。使用它非常简单,它们具有磁盘/内存缓存,您可以在不使用复杂解决方案的情况下将图像加载到单独的线程中。

+0

谢谢。这是否适合我在这里想要实现的目标? –

+0

其实我没有得到你想要达到的。但它会在工作线程中加载图像,这是这个库可以做的最简单的事情。 –

+0

这是一个伟大的库,对于这种情况我不认为它是需要的。但是,如果你确实需要它,这不是很难把你的应用程序,但我们仍然需要首先找出你的问题 –

-1

使用类似Glide的库。您可以简单地添加在摇篮滑翔依赖性: 编译“com.github.bumptech.glide:滑翔:3.7.0”

,您可以通过书面简单地加载图像: Glide.with(上下文).load(” IMAGE_URL“)代入(imagevie_name)。

+0

还注意到有版本4发布 –

+0

好的建议,但不回答这个问题。 – njzk2

+0

我认为它有帮助,我一直在努力弄清楚,它可能更容易使用,但我不确定。 OP的代码对我很好,虽然我不知道OP的例子中有多大的图片是 –

1

好了,所以这是我的想法在评论中谈到

1)我复制你的代码和XML完全按照您发布,它为我工作得很好,随着中说我要添加一些东西后

编辑:不知道这事,但这些都是我的进口

import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.view.View; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.ImageView; 
import android.widget.Toast; 
import java.io.BufferedInputStream; 
import java.io.InputStream; 
import java.net.URL; 
import java.net.URLConnection; 

我认为这可能是这些可能性

2)M组合请确保您的网址正常,请确保您添加了http或https部分。确保你的自动更正没有添加任何东西(我的结尾添加了一段时间)。因为这是我无法测试的唯一部分,所以我觉得这可能是因为它可能是

3)记录所有内容,在将URL传递到URL对象之前记录它,以确保它是正确的,查找ANY例外

4)如果url不正确,url不会显示,如果url无法解析有效的URL(如前所述),它将被捕获在正在创建的URL对象周围的try catch中,并且不会调用异步任务(发生在我身上的时候,我把假的网址,我得到了异常,所以请试着留意)

编辑:对于数字4,我得到了不正确的协议的例外(遗漏http),但如果链接是错误的,然后是的,吐司出现了

5)尝试使用其他图片,你永远不知道:d

编辑:尝试这与滑翔,

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

btn = (Button) findViewById(R.id.button); 
et = (EditText) findViewById(R.id.editText); 

btn.setOnClickListener(new View.OnClickListener() { 
    public void onClick(View v) { 
     try { 
      Glide.with(MainActivity.this) 
        .load(et.getText().toString()) 
        .into((ImageView) findViewById(R.id.imageView)); 

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

不需要异步

和一个多解决方案,而滑翔

@Override 
     protected Bitmap doInBackground(URL... params) { 
      URL url = params[0]; 
      HttpURLConnection connection = null; 
      Bitmap bitmap = null; 


      try { 
       connection = (HttpURLConnection) url.openConnection(); 
       connection.setDoInput(true); 
       connection.connect(); 
       InputStream input = connection.getInputStream(); 
       BufferedInputStream bis = new BufferedInputStream(input); 
       bitmap = BitmapFactory.decodeStream(bis); 
       bis.close(); 
       input.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 



    return bitmap; 
    } 
+0

感谢您的好先生,为您的时间帮助完成这项任务,我很感激。我将最终达到最后! –

+0

让我知道,我非常好奇这个问题。如果我们可以在这个网站上聊天,给我发消息或我想帮助的东西。 –

+0

我的吐司消息现在正在显示,就像您提到尝试新的网址一样。但它是一个有效的URL http://tny.im/ayy到一个图像,所以我不知道什么是错的 –

2

正如你在评论中提到的,你的图片在这个网址

http://tny.im/ayy

此网址没有指向的图像。它指向一个重定向,(http状态301)。

有可能您的连接没有遵循重定向。

您可以指示连接到遵循重定向:

((HttpURLConnection) connection).setInstanceFollowRedirects(true); 
+0

感谢您的建议,但那并不幸运 –

+0

很高兴知道这种重定向方法! –

0

//添加以下dependecny滑翔

compile 'com.github.bumptech.glide:glide:3.7.0' 



new LoadImageFromUrlTask().execute(imageURL); 




public class LoadImageFromUrlTask extends AsyncTask<String, Void, Bitmap> { 
     String downloadPath = ""; 
     String sdCardBasePath = Environment.getExternalStorageDirectory().toString(); 
     @Override 
     protected Bitmap doInBackground(String... args) { 
      try { 
       downloadPath = args[0]; 
       return BitmapFactory.decodeStream((InputStream) new URL(downloadPath).getContent()); 

      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 

     @Override 
     protected void onPostExecute(Bitmap bitmap) { 
      if (bitmap != null) { 
       String photoFileName = downloadPath.substring(downloadPath.lastIndexOf('/') + 1); 
       String saveImagePath = ""; 

       int dotposition = photoFileName.lastIndexOf("."); 
       String filename_Without_Ext = photoFileName.substring(0, dotposition); 
       String Ext = photoFileName.substring(dotposition + 1, photoFileName.length()); 
       String newFileName = filename_Without_Ext + "." + Ext; 
       saveImagePath = sdCardBasePath + "/" + newFileName; 
       saveBitmapToJPEGFile(MainActivity.this, bitmap, new File(saveImagePath), 900); 
       saveBitmapToFile(MainActivity.this, myImageViewImage, saveImagePath); 
      } else { 
       myImageViewImage.setImageResource(R.drawable.default_photo); 
      } 
     } 
    } 

    public Boolean saveBitmapToFile(Context ctx, Bitmap tempBitmap, File targetFile, int i) { 
     Boolean result = true; 
     if (tempBitmap != null) { 
      FileOutputStream out = null; 
      try { 
       out = new FileOutputStream(targetFile); 
       tempBitmap.compress(Bitmap.CompressFormat.JPEG, CommonUtils.JPEG_COMPRESION_RATIO_DEFAULT, out); 

      } catch (FileNotFoundException e) { 
       result = false; 
       e.printStackTrace(); 
      } 
      if (out != null) { 
       try { 
        out.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } else { 
      result = false; 
     } 
     return result; 
    } 

    public void loadImageWithGlide(Context theCtx, ImageView theImageView, String theUrl) { 
     Glide.with(theCtx) 
       .load(theUrl) 
       .diskCacheStrategy(DiskCacheStrategy.NONE) 
       .skipMemoryCache(true) 
       .into(theImageView); 

    } 
0

我无法得到我最初发布,即使工作的代码你们所有人都帮忙。非常感谢任何人发布的建议!无论如何,我回去了,终于用更少的代码工作了! 这里是我的工作代码

public class MainActivity extends AppCompatActivity { 
    EditText editText; 
    Bitmap bitmap; 
    ImageView view; 
    Button btn; 
    ProgressDialog pd; 

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

     editText = (EditText) findViewById(R.id.inputFileUrl); 
     view = (ImageView) findViewById(R.id.imageView); 
     btn = (Button) findViewById(R.id.retrieveFileUrl); 
    } 

    public void buttonClicked(View view) { 

     String stringUrl = editText.getText().toString(); 
     new DownloadTask().execute(stringUrl); 
    } 


    // Uses AsyncTask to create a task away from the main UI thread. This task takes 
    // URL string and uses it to create an HttpUrlConnection. Once the connection 
    // has been established, the AsyncTask downloads the contents of the webpage as 
    // an InputStream. Finally, the InputStream is converted into a string, which is 
    // displayed in the UI by the AsyncTask's onPostExecute method. 
    public class DownloadTask extends AsyncTask<String, Void, Bitmap> { 

     @Override 
     protected void onPreExecute() { 
      //Create PD, SET Properties 
      pd = new ProgressDialog(MainActivity.this); 
      pd.setTitle("Image Downloader"); 
      pd.setMessage("Downloading...."); 
      pd.setIndeterminate(false); 
      pd.show(); 
     } 

     @Override 
     protected Bitmap doInBackground(String... urls) { 

      String url = urls[0]; 

      try { 
       bitmap = BitmapFactory.decodeStream(new URL(url).openConnection().getInputStream()); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      return bitmap; 
     } 
     // onPostExecute displays the results of the AsyncTask. 

     @Override 
     protected void onPostExecute(Bitmap url) { 
      if (bitmap != null) { 
       super.onPostExecute(url); 
       view.setImageBitmap(url); 
       //Dismiss 
       pd.dismiss(); 
      } else { 
       Toast.makeText(getApplicationContext(), "Failed to Download Image", Toast.LENGTH_LONG).show(); 
       //Dismiss 
       pd.dismiss(); 
      } 
     } 
    } 
} 
+0

好,只要它有效,对我来说它看起来一样,所以不知道为什么,但只要它的工作正确?无论如何只有一个注意ProgressDialog已被弃用,所以只是一个fyi :) –