日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android异步加载

發布時間:2025/4/16 Android 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android异步加载 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

為什么要異步加載:

為了用戶體驗,避免卡頓

Android系統要求使用異步加載,耗時操作會阻塞UI線程

異步加載的常用的方式:

多線程/線程池

AsyncTask


以下以加載網絡圖片為示例

在主類之外聲明一個單獨的MyBean類:

class MyBean{public String MyIconUrl;public String MyTitle;public String MyContent; }

和一個MyAdapter類:

public class MyAdapter extends BaseAdapter{private List<MyBean> mList;private LayoutInflater mInflater;public MyAdapter(Context context, List<MyBean> data){mList = data;mInflater = LayoutInflater.from(context);}public int getCount(){return mList.size();}public Object getItem(int position){return mList.get(position);}public long getItemId(int position){return position;}public View getView(int position, View convertView, ViewGroup parent){ViewHolder viewHolder = null;if(convertView == null){viewHolder = new ViewHolder();convertView = mInflater.inflate(R.layout.item_layout, null);viewHolder.ivIcon = (ImageView)convertView.findViewById(R.id.iv_icon);viewHolder.tvTitle = (TextView)convertView.findViewById(R.id.tv_title);viewHolder.tvContent = (TextView)convertView.findViewById(R.id.tv_content);convertView.setTag(viewHolder);}else{viewHolder = (ViewHolder)convertView.getTag();}viewHolder.ivIcon.setImageResource(R.mipmap.ic_launcher);//這是使用默認的ic_launcher作為圖標 //-----------------下述是調用異步加載圖片的內容作為圖標 new ImageLoader().showImageByThread(viewHolder.ivIcon, mList.get(position).myIconUrl); //-----------------viewHolder.tvTitle.setText(mList.get(position).MyTitle);viewHolder.tvContent.setText(mList.get(position).MyContent);return convertView;}class ViewHolder{public TextView tvTitle, tvContent;public ImageView ivIcon;} }

接下來是主類中的方法:

private ListView mListView; private static String URL = "http://www.xxxxxxxxx.com/xxx/xxx/xxx";protected void OnCreate(Bundle savedInstanceState){super.OnCreate(savedInstanceState);setContentView(R.Layout.activity_main);mListView = (ListView)findViewById(R.id.lv_main);new MyAsyncTask().execute(URL); }

private List<MyBean> getJsonData(String url){//將Url的Json數據轉化為所封裝的MyBean對象List<MyBean> myBeanList = new ArrayList<>();try{String jsonString = readStream(new URL(url).openStream());//上述語句功能與url.openConnection().getInputStream()相同,//可根據URL直接聯網獲取網絡數據,簡單粗暴,返回值類型為InputStreamJSONObject jsonObject;MyBean myBean;try{jsonObject = new jsonObject(jsonString);JSONArray jsonArray = jsonObject.getJSONArray("data");for(int i =0;i<jsonArray.length();i++){jsonObject = jsonArray.getJSONObject(i);myBean = new MyBean();myBean.MyIconUrl = jsonObject.getString("picSmall");myBean.MyTitle = jsonObject.getString("name");myBean.MyContent = jsonObject.getString("description");myBeanList.add(myBean);//循環完畢時,將所有數據加入MyBean對象中,之后就可以將數據設置在ListView中}}catch(JSONException e){e.printStackTrace();}}catch(IOException e){e.printStackTrace();}return myBeanList; }private String readStream(InputStream is){//通過InputStream解析網頁返回的數據InputSrteamReader isr;String result = "";try{String line = "";isr = new InputStream(is, "utf-8");BufferedReader br = new BufferedReader(isr);while((line = br.readLine())!= null){result+=line;}}catch(UnsupportedEncodingException e){e.printStackTrace();}catch(IOException e){e.printStackTrace();}return result; }class MyAsyncTask extends AsyncTask<String, Void, List<MyBean>>{//實現網絡的異步訪問protected List<MyBean> doInBackground(String... params){return getJsonData(params[0]);}protected void onPostExecute(List<MyBean> myBean){super.onPostExecute(myBean);MyAdapter adapter = new MyAdapter(MainActivity.this, myBean );mListView.setAdapter(adapter);} }上述實現了ListView圖文混排

接下來是對圖像的異步加載:

public class ImageLoader{private ImageView mImageView;private Handler mHandler = new Handler();private Handler handler = new Handler(){public void handleMessage(Message msg){super.handleMessage(msg);mImageView.setImageBitmap((Bitmap)msg.obj);}}public void showImageByThread(ImageView imageView, String url){mImageView = imageView;new Thread(){public void run(){super.run();Bitmap bitmao = getBitmapFromURL(url);Message message = Message.obtain();message.obj = bitmap;mHandler.sendMessage(message);}}.start();}public Bitmap getBitmapFromURL(String urlStirng){Bitmap bitmap;InputStream is;try{URL url = new URL(urlStirng);HttpURLConnection connection = (HttpURLConnection)url.openConnection();is = new BufferedInputStream(connection.getInputStream());bitmap = BitmapFactory.decodeStream(is);connection.disconnect();return bitmap;}catch(java.io.IOException e){e.printStackTrace();}finally{is.close();}return null;} }事實上,上面的方法,在網速不是很快的時候,會出現刷新時圖片錯亂的現象,因為ListView的緩存機制導致圖片顯示錯位,則只需要改進一步,在MyAdapter類中的getView()方法中增加三行代碼:

viewHolder.ivIcon.setImageResource(R.mipmap.ic_launcher);String utl = mList.get(position).MyIconUrl;viewHolder.ivIcon.setTag(utl);new ImageLoader().showImageByThread(viewHolder.ivIcon, url);viewHolder.tvTitle.setText(mList.get(position).MyTitle);viewHolder.tvContent.setText(mList.get(position).MyContent);return convertView;之后在ImageLoader類中handleMessage()方法中增加判斷語句,最終修改為:

public class ImageLoader{private ImageView mImageView;private Handler mHandler = new Handler();private String mUrl;private Handler handler = new Handler(){public void handleMessage(Message msg){super.handleMessage(msg);if(mImageView.getTag().equals(mUrl))mImageView.setImageBitmap((Bitmap)msg.obj);}}public void showImageByThread(ImageView imageView, String url){mImageView = imageView;mUrl = url;new Thread(){public void run(){super.run();Bitmap bitmao = getBitmapFromURL(url);Message message = Message.obtain();message.obj = bitmap;mHandler.sendMessage(message);}}.start();}public Bitmap getBitmapFromURL(String urlStirng){Bitmap bitmap;InputStream is;try{URL url = new URL(urlStirng);HttpURLConnection connection = (HttpURLConnection)url.openConnection();is = new BufferedInputStream(connection.getInputStream());bitmap = BitmapFactory.decodeStream(is);connection.disconnect();return bitmap;}catch(java.io.IOException e){e.printStackTrace();}finally{is.close();}return null;} }一般有兩種辦法避免ListView的緩存特性帶來的ListView的Item的錯亂,一種是在BaseAdapter中設置tag,將身份驗證信息與相應的Item綁定,在加載時判斷身份驗證信息是否正確,正確才設置圖片操作,第二種,是使用成員變量,將對應的數據進行緩存,從而避免網絡下載時間不確定導致的時序的混亂。大部分的異步加載錯誤都可以使用這兩種辦法解決。


使用AsyncTask()方法異步加載

public void showImageByAsyncTask(ImageView imageView, String url){new MyAsyncTask(imageView).execute(url); }private class MyAsyncTask extends AsyncTask<String, Void, Bitmap>{private ImageView imageView;public MyAsyncTask(ImageView imageView){mImageView = imageView;}protected Bitmap doInBackground(String... params){return getBitmapFromURL(params[0]);}protected void onPostExecute(Bitmap bitmap){super.onPostExecute(bitmap);mImageView.setImageBitmap(bitmap);} }
之后再回到MyAdapter類中,將多線程的方法加載圖片的語句換掉:

//new ImageLoader().showImageByThread(viewHolder.ivIcon, url);new ImageLoader().showImageByAsyncTask(viewHolder.ivIcon, url);同樣,AsyncTask方法也會出現刷新時圖片錯亂的現象,因為AsyncTask本身就是基于多線程,所以對其進行處理,修改之后:

public void showImageByAsyncTask(ImageView imageView, String url){new MyAsyncTask(imageView, url).execute(url); }private class MyAsyncTask extends AsyncTask<String, Void, Bitmap>{private ImageView imageView;private String mUrl;public MyAsyncTask(ImageView imageView, String url){mImageView = imageView;mUrl = url;}protected Bitmap doInBackground(String... params){return getBitmapFromURL(params[0]);}protected void onPostExecute(Bitmap bitmap){super.onPostExecute(bitmap);if(mImageView.getTag().equals(mUrl))mImageView.setImageBitmap(bitmap);} }
至此,便實現了異步加載網絡圖片。








總結

以上是生活随笔為你收集整理的Android异步加载的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。