转载请标明源地址:[http://blog.csdn.net/gaolei1201/article/details/50392478](http://blog.csdn.net/gaolei1201/article/details/50392478)
以前项目中做过上传头像和仿QQ空间、微博发表文字和图片,也是花费了好多精力和时间多。现在花了几天时间做了整理与大家分享一下。下面把几个重要点列一下:
1.下面会把Demo源码奉献给大家,用的是以前公司的接口,首先需要登录才能更新头像和发表图文
2.我在项目中用的是OKHttp框架来实现网络请求,详情可参考:[Android OkHttp完全解析](http://blog.csdn.net/lmj623565791/article/details/47911083),展现图片用的是UniversalImageLoader
3.展示本地图片时一定要压缩,不然图片大的话一个几M,容易出现OOM
4.上传图片时也要压缩,不然图片大的话耗费时间太长,以及别人浏览图片时太耗流量
5.在获取上传图片时,刚开始是肯定获取不到的,因为一张图片上传需要几秒钟,为了较好的用户体验可以先展示本地图片,上传成功后下次再展示网络图片;另一种方法就是把所有图片都上传完成,然后再获取发表的内容
如图:
![](https://box.kancloud.cn/2016-02-29_56d3fcdb05e43.jpg)
![](https://box.kancloud.cn/2016-02-29_56d3fcdb1fdcd.jpg)
![](https://box.kancloud.cn/2016-02-29_56d3fcdb3095d.jpg)
# 下面是网络请求封装类,别的类用接口回调可以获取请求结果
~~~
<span style="font-size:14px;">public class NetRequest {
private MyInterface.NetRequestIterface netRequestIterface;
private Context context;
public NetRequest(MyInterface.NetRequestIterface netRequestIterface, Context context) {
this.netRequestIterface = netRequestIterface;
this.context = context;
}
/**
* 网络请求用的是OKHttp,这个开源项目的好处是1.Android 6.0后不支持HttpClient请求,而它使用HttpUrlConnection 2.默认支持https
*/
public void httpRequest(Map<String, Object> map, final String requestUrl) {
if (!CommonUtils.getUtilInstance().isConnectingToInternet(context)) {
Toast.makeText(context,
context.getString(R.string.internet_fail_connect),Toast.LENGTH_LONG).show();
return;
}
OkHttpClient mOkHttpClient = new OkHttpClient();
FormEncodingBuilder builder = new FormEncodingBuilder();
if (null != map && !map.isEmpty())
for (String key : map.keySet()) {
builder.add(key, map.get(key)+"");
}
if(UserInfoUtil.getInstance().getAuthKey()!=null) {
builder.add("authKey", UserInfoUtil.getInstance().getAuthKey());
}
Log.d("gaolei", " authKey------------------"+UserInfoUtil.getInstance().getAuthKey());
Request request = new Request.Builder()
.url(requestUrl)
.post(builder.build())
.build();
try {
mOkHttpClient.setConnectTimeout(5000, TimeUnit.MILLISECONDS);
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Request request, IOException e) {
netRequestIterface.exception(e, requestUrl);
}
@Override
public void onResponse(final Response response) throws IOException {
String result = response.body().string();
netRequestIterface.changeView(result, requestUrl);
}
});
}catch (Exception e){
}
}
}
</span>
~~~
下面是压缩图片
~~~
<span style="font-size:14px;"> //注意显示本地图片时一定要压缩质量,不然容易出现OOM
public Bitmap trasformToZoomPhotoAndLessMemory(String url) {
File file = new File(url);
Log.d("gaolei", "file.length()--------original-------------" + file.length());
BitmapFactory.Options options = new BitmapFactory.Options();
// 通过这个bitmap获取图片的宽和高
options.inJustDecodeBounds = true;
int inSampleSize = 1;
if (file.length() < 256 * 1024) {
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
} else if (file.length() < 512 * 1024) {
options.inPreferredConfig = Bitmap.Config.RGB_565;
options.inSampleSize = 2;
inSampleSize = 2;
} else if (file.length() < 1024 * 1024) {
options.inPreferredConfig = Bitmap.Config.RGB_565;
options.inSampleSize = 4;
inSampleSize = 4;
} else {
options.inPreferredConfig = Bitmap.Config.RGB_565;
options.inSampleSize = 6;
inSampleSize = 6;
}
options.inPurgeable = true;
options.inInputShareable = true;
// 注意这次要把options.inJustDecodeBounds 设为 false,这次图片是要读取出来的
options.inJustDecodeBounds = false;
Log.d("gaolei", "inSampleSize-----------------" + inSampleSize);
int degree = readPictureDegree(file.getAbsolutePath());
// Log.d("gaolei", "degree------------uploadImg--------------" +
// degree);
InputStream is = null;
try {
is = new FileInputStream(url);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Bitmap cameraBitmap = BitmapFactory.decodeStream(is, null, options);
// Bitmap cameraBitmap = BitmapFactory.decodeFile(url, options);
Bitmap photo = rotaingImageView(degree, cameraBitmap);
if (is != null) {
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return photo;
}</span>
~~~
下面是把图片byte转化为字符串上传到服务器
~~~
<span style="font-size:14px;"> //请注意:上传图片时 我是把图片byte转化为字符串 上传到服务器,当然还可以用1.stream上传到服务器 2.Socket上传到服务器,不过我没试过
public void uploadUserPhotoNew(final String filePath) {
uploading_photo_progress.setVisibility(View.VISIBLE);
//为什么另开一个线程呢?因为要把图片字节流转化为字符串上传,比较耗时,阻塞UI线程,会使应用卡卡卡,所以要另开一线程
new Thread() {
public void run() {
String fileType = UploadPhotoUtil.getInstance().getFileType(filePath);
String fileString = UploadPhotoUtil.getInstance().getUploadPhotoZoomString(
filePath);
Map<String, Object> map = new HashMap<String, Object>();
map.put("imgType", fileType);
map.put("imgBody", fileString);
Message msg = handler.obtainMessage();
msg.obj = map;
msg.what = SAVE_PHOTO_IMAGE;
handler.sendMessage(msg);
}
}.start();
}</span>
~~~
下面是展示发表图文ListView的Adapter,这里比较重要,因为图片上传需要一段时间,马上获取发表的图文时,肯定显示不出来图片,现在先显示本地的,等下次进入时显示网络的
~~~
<span style="font-size:14px;">public class ThemeListViewAdapter extends BaseAdapter {
private LayoutInflater inflater;
private List<ThemeObject> list;
private Context context;
private List<String> uploadImgUrlList;
public ThemeListViewAdapter(List<ThemeObject> list,
List<String> uploadImgUrlList, Context context) {
inflater = LayoutInflater.from(context);
this.list = list;
this.uploadImgUrlList = uploadImgUrlList;
this.context = context;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public void changeList(List<ThemeObject> list) {
this.list = list;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.theme_listview_items, null);
holder.user_photo = (ImageView) convertView
.findViewById(R.id.user_photo);
holder.theme_img1 = (ImageView) convertView
.findViewById(R.id.theme_img1);
holder.theme_img2 = (ImageView) convertView
.findViewById(R.id.theme_img2);
holder.theme_img3 = (ImageView) convertView
.findViewById(R.id.theme_img3);
holder.theme_title = (TextView) convertView
.findViewById(R.id.theme_title);
holder.theme_desc = (TextView) convertView
.findViewById(R.id.theme_desc);
holder.user_name = (TextView) convertView
.findViewById(R.id.user_name);
holder.publish_theme_time = (TextView) convertView
.findViewById(R.id.publish_theme_time);
holder.theme_reply_num = (TextView) convertView
.findViewById(R.id.theme_reply_num);
holder.theme_praise_num = (TextView) convertView
.findViewById(R.id.theme_praise_num);
holder.game_playing_prefix = (TextView) convertView
.findViewById(R.id.game_playing_prefix);
holder.game_playing = (TextView) convertView
.findViewById(R.id.game_playing);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.user_photo.setTag(position + "");
holder.theme_img1.setTag(position + "");
holder.theme_img2.setTag(position + "");
holder.theme_img3.setTag(position + "");
holder.game_playing_prefix.setTag(position + "");
holder.game_playing.setTag(position + "");
if (list.size() > 0) {
final ThemeObject object = list.get(position);
if (holder.user_photo.getTag().equals("" + position)) {
if (object.getUserPhoto() != null) {
new CommonUtils().displayCircleImage(object.getUserPhoto(),
holder.user_photo, "photo");
} else {
holder.user_photo.setImageDrawable(context.getResources()
.getDrawable(R.drawable.personal_default_photo));
}
List<PictureList> themePictureList = object.getPictureList();
int pictureListSize = themePictureList.size();
List<String> pictureUrlList = new ArrayList<String>();
for (int i = 0; i < themePictureList.size(); i++) {
pictureUrlList.add(themePictureList.get(i).getUrl());
}
Log.d("gaolei", "themePictureList.size()------------" + position + "-------" + themePictureList.size());
int uploadImgUrlListSize = uploadImgUrlList.size();
Log.d("gaolei", "uploadImgUrlListSize------------" + position + "-------" + uploadImgUrlListSize);
if (pictureListSize == 0) {
holder.theme_img1.setVisibility(View.GONE);
holder.theme_img2.setVisibility(View.GONE);
holder.theme_img3.setVisibility(View.GONE);
}
if (pictureListSize == 1) {
holder.theme_img1.setVisibility(View.VISIBLE);
if (holder.theme_img1.getTag().equals("" + position)) {
CommonUtils.getUtilInstance().displayLowQualityInImage(pictureUrlList.get(0),
holder.theme_img1);
}
}
if (pictureListSize == 2) {
holder.theme_img1.setVisibility(View.VISIBLE);
holder.theme_img2.setVisibility(View.VISIBLE);
if (holder.theme_img1.getTag().equals("" + position)) {
CommonUtils.getUtilInstance().displayLowQualityInImage(pictureUrlList.get(0),
holder.theme_img1);
}
if (holder.theme_img2.getTag().equals("" + position)) {
CommonUtils.getUtilInstance().displayLowQualityInImage(pictureUrlList.get(1),
holder.theme_img2);
}
}
if (pictureListSize == 3) {
holder.theme_img1.setVisibility(View.VISIBLE);
holder.theme_img2.setVisibility(View.VISIBLE);
holder.theme_img3.setVisibility(View.VISIBLE);
if (holder.theme_img1.getTag().equals("" + position)) {
CommonUtils.getUtilInstance().displayLowQualityInImage(pictureUrlList.get(0),
holder.theme_img1);
}
if (holder.theme_img2.getTag().equals("" + position)) {
CommonUtils.getUtilInstance().displayLowQualityInImage(pictureUrlList.get(1),
holder.theme_img2);
}
if (holder.theme_img3.getTag().equals("" + position)) {
CommonUtils.getUtilInstance().displayLowQualityInImage(pictureUrlList.get(2),
holder.theme_img3);
}
}
//这里比较重要,因为图片上传需要一段时间,马上获取发表的图文时,肯定显示不出来图片,现在先显示本地的,等下次进入时显示网络的
if (position == 0) {
if (uploadImgUrlListSize == 1) {
holder.theme_img1.setVisibility(View.VISIBLE);
if (holder.theme_img1.getTag().equals("" + position)) {
Bitmap bitmap = UploadPhotoUtil.getInstance().trasformToZoomBitmapAndLessMemory(uploadImgUrlList.get(0));
holder.theme_img1.setImageDrawable(new BitmapDrawable(context.getResources(), bitmap));
}
}
if (uploadImgUrlListSize == 2) {
holder.theme_img1.setVisibility(View.VISIBLE);
holder.theme_img2.setVisibility(View.VISIBLE);
if (holder.theme_img1.getTag().equals("" + position)) {
Bitmap bitmap = UploadPhotoUtil.getInstance().trasformToZoomBitmapAndLessMemory(uploadImgUrlList.get(0));
holder.theme_img1.setImageDrawable(new BitmapDrawable(context.getResources(), bitmap));
}
if (holder.theme_img2.getTag().equals("" + position)) {
Bitmap bitmap = UploadPhotoUtil.getInstance().trasformToZoomBitmapAndLessMemory(uploadImgUrlList.get(1));
holder.theme_img2.setImageDrawable(new BitmapDrawable(context.getResources(), bitmap));
}
}
if (uploadImgUrlListSize == 3) {
holder.theme_img1.setVisibility(View.VISIBLE);
holder.theme_img2.setVisibility(View.VISIBLE);
holder.theme_img3.setVisibility(View.VISIBLE);
if (holder.theme_img1.getTag().equals("" + position)) {
Bitmap bitmap = UploadPhotoUtil.getInstance().trasformToZoomBitmapAndLessMemory(uploadImgUrlList.get(0));
holder.theme_img1.setImageDrawable(new BitmapDrawable(context.getResources(), bitmap));
}
if (holder.theme_img2.getTag().equals("" + position)) {
Bitmap bitmap = UploadPhotoUtil.getInstance().trasformToZoomBitmapAndLessMemory(uploadImgUrlList.get(1));
holder.theme_img2.setImageDrawable(new BitmapDrawable(context.getResources(), bitmap));
}
if (holder.theme_img3.getTag().equals("" + position)) {
Bitmap bitmap = UploadPhotoUtil.getInstance().trasformToZoomBitmapAndLessMemory(uploadImgUrlList.get(2));
holder.theme_img3.setImageDrawable(new BitmapDrawable(context.getResources(), bitmap));
}
}
}
holder.user_name.setText(object.getUserName());
holder.theme_title.setText(object.getThemeTitle());
holder.theme_desc.setText(object.getThemeDescr());
holder.theme_reply_num.setText(object.getReplyNum() + "");
holder.publish_theme_time.setText(CommonUtils.getUtilInstance()
.transformMillisToDate(object.getCreateTime()));
holder.theme_praise_num.setText(object.getPraiseNum() + "");
}
holder.user_photo.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
}
return convertView;
}
class ViewHolder {
ImageView user_photo, theme_img1, theme_img2, theme_img3;
TextView user_name, theme_title, theme_desc, publish_theme_time,
theme_reply_num, theme_praise_num, game_playing,
game_playing_prefix;
}
}</span>
~~~
另外的开源项目地址:[http://www.itlanbao.com/code/20150810/10044/100222.html](http://www.itlanbao.com/code/20150810/10044/100222.html) ,效果如下图:
![](https://box.kancloud.cn/2016-02-29_56d3fcdb62a6a.jpg)
[源码下载地址,欢迎光临......](https://github.com/gaoleiandroid1201/UploadPhoto)