android jsoup解析服务端数据客户端源码讲解。

  大家好,本人六年以上的android开发经验,做过不下百款应用软件,之前应用接入点广告还能挣点钱,如今,真的不挣钱,现将手中自己开发的一个完整客户端项目给大家分享。希望大家能喜欢,多提意见。

这个项目不需要服务端数据支持,主要使用jsoup解析糗事百科数据,从而实现自己客户端数据的呈现.

  

这个是项目中item分组排序类


import com.my.li.funny.adapter.DragAdapter;
import com.my.li.funny.adapter.OtherAdapter;
import com.my.li.funny.database.DataBase;
import com.my.li.funny.database.tables.NewsTitleTable;
import com.my.li.funny.entitys.NewsTitle;
import com.my.li.funny.widgets.DragGrid;
import com.my.li.funny.widgets.OtherGridView;


public class ChannelMageActivity extends Activity implements OnItemClickListener,SlidingPaneLayout.PanelSlideListener {


/** 用户栏目的GRIDVIEW */
private DragGrid userGridView;
/** 其它栏目的GRIDVIEW */
private OtherGridView otherGridView;
/** 用户栏目对应的适配器,可以拖动 */
private DragAdapter userAdapter;
/** 其它栏目对应的适配器 */
private OtherAdapter otherAdapter;
/** 其它栏目列表 */
private List<NewsTitle> otherChannelList = new ArrayList<NewsTitle>();
/** 用户栏目列表 */
private List<NewsTitle> userChannelList = new ArrayList<NewsTitle>();
/** 是否在移动,由于这边是动画结束后才进行的数据更替,设置这个限制为了避免操作太频繁造成的数据错乱。 */
boolean isMove = false;
private boolean isClick = false;


private DataBase mDataBase;
private NewsTitleTable mNewsTitleTable;


private final String selectUser = "1";
private final String selectOther = "0";
// 更新首页title数据广播
private final String UPDATEBROADCAST = "com.updtetitle.main";


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.subscribe_activity);
initView();
initData();
initSlideBackClose();
}


/** 初始化布局 */
private void initView() {
userGridView = (DragGrid) findViewById(R.id.userGridView);
otherGridView = (OtherGridView) findViewById(R.id.otherGridView);
findViewById(R.id.back_text).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
finish();
}
});
}


private void initData() {
mDataBase = DataBase.getInstance();
mNewsTitleTable = mDataBase.getNewsTitleTable();
userChannelList = mNewsTitleTable.getTitleForIndex(this, selectUser);
otherChannelList = mNewsTitleTable.getTitleForIndex(this, selectOther);
userAdapter = new DragAdapter(this, userChannelList);
userGridView.setAdapter(userAdapter);
otherAdapter = new OtherAdapter(this, otherChannelList);
otherGridView.setAdapter(this.otherAdapter);
// 设置GRIDVIEW的ITEM的点击监听
otherGridView.setOnItemClickListener(this);
userGridView.setOnItemClickListener(this);


}


/** GRIDVIEW对应的ITEM点击监听接口 */
@Override
public void onItemClick(AdapterView<?> parent, final View view, final int position, long id) {
// 如果点击的时候,之前动画还没结束,那么就让点击事件无效
if (isMove) {
return;
}
switch (parent.getId()) {
case R.id.userGridView:
// position为 0,1 的不可以进行任何操作
// if (position != 0) {
if (!isClick) {
isClick = true;
}
final ImageView moveImageView_user = getView(view);
if (moveImageView_user != null) {
TextView newTextView = (TextView) view.findViewById(R.id.text_item);
final int[] startLocation = new int[2];
newTextView.getLocationInWindow(startLocation);
final NewsTitle channel = ((DragAdapter) parent.getAdapter()).getItem(position);// 获取点击的频道内容
otherAdapter.setVisible(false);
// 添加到最后一个
otherAdapter.addItem(channel);
new Handler().postDelayed(new Runnable() {
public void run() {
try {
int[] endLocation = new int[2];
// 获取终点的坐标
otherGridView.getChildAt(otherGridView.getLastVisiblePosition()).getLocationInWindow(endLocation);
MoveAnim(moveImageView_user, startLocation, endLocation, channel, userGridView);
userAdapter.setRemove(position);
} catch (Exception localException) {
}
}
}, 50L);
}
// }
break;
case R.id.otherGridView:
final ImageView moveImageView = getView(view);
if (moveImageView != null) {
if (!isClick) {
isClick = true;
}
TextView newTextView = (TextView) view.findViewById(R.id.text_item);
final int[] startLocation = new int[2];
newTextView.getLocationInWindow(startLocation);
final NewsTitle channel = ((OtherAdapter) parent.getAdapter()).getItem(position);
userAdapter.setVisible(false);
// 添加到最后一个
userAdapter.addItem(channel);
new Handler().postDelayed(new Runnable() {
public void run() {
try {
int[] endLocation = new int[2];
// 获取终点的坐标
userGridView.getChildAt(userGridView.getLastVisiblePosition()).getLocationInWindow(endLocation);
MoveAnim(moveImageView, startLocation, endLocation, channel, otherGridView);
otherAdapter.setRemove(position);
} catch (Exception localException) {
}
}
}, 50L);
}
break;
default:
break;
}
}


/**
* 点击ITEM移动动画

* @param moveView
* @param startLocation
* @param endLocation
* @param moveChannel
* @param clickGridView
*/
private void MoveAnim(View moveView, int[] startLocation, int[] endLocation, final NewsTitle moveChannel, final GridView clickGridView) {
int[] initLocation = new int[2];
// 获取传递过来的VIEW的坐标
moveView.getLocationInWindow(initLocation);
// 得到要移动的VIEW,并放入对应的容器中
final ViewGroup moveViewGroup = getMoveViewGroup();
final View mMoveView = getMoveView(moveViewGroup, moveView, initLocation);
// 创建移动动画
TranslateAnimation moveAnimation = new TranslateAnimation(startLocation[0], endLocation[0], startLocation[1], endLocation[1]);
moveAnimation.setDuration(300L);// 动画时间
// 动画配置
AnimationSet moveAnimationSet = new AnimationSet(true);
moveAnimationSet.setFillAfter(false);// 动画效果执行完毕后,View对象不保留在终止的位置
moveAnimationSet.addAnimation(moveAnimation);
mMoveView.startAnimation(moveAnimationSet);
moveAnimationSet.setAnimationListener(new AnimationListener() {


@Override
public void onAnimationStart(Animation animation) {
isMove = true;
}


@Override
public void onAnimationRepeat(Animation animation) {
}


@Override
public void onAnimationEnd(Animation animation) {
moveViewGroup.removeView(mMoveView);
// instanceof 方法判断2边实例是不是一样,判断点击的是DragGrid还是OtherGridView
if (clickGridView instanceof DragGrid) {
otherAdapter.setVisible(true);
otherAdapter.notifyDataSetChanged();
userAdapter.remove();
} else {
userAdapter.setVisible(true);
userAdapter.notifyDataSetChanged();
otherAdapter.remove();
}
isMove = false;
}
});
}


/**
* 获取移动的VIEW,放入对应ViewGroup布局容器

* @param viewGroup
* @param view
* @param initLocation
* @return
*/
private View getMoveView(ViewGroup viewGroup, View view, int[] initLocation) {
int x = initLocation[0];
int y = initLocation[1];
viewGroup.addView(view);
LinearLayout.LayoutParams mLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
mLayoutParams.leftMargin = x;
mLayoutParams.topMargin = y;
view.setLayoutParams(mLayoutParams);
return view;
}


/**
* 创建移动的ITEM对应的ViewGroup布局容器
*/
private ViewGroup getMoveViewGroup() {
ViewGroup moveViewGroup = (ViewGroup) getWindow().getDecorView();
LinearLayout moveLinearLayout = new LinearLayout(this);
moveLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
moveViewGroup.addView(moveLinearLayout);
return moveLinearLayout;
}


/**
* 获取点击的Item的对应View,

* @param view
* @return
*/
private ImageView getView(View view) {
view.destroyDrawingCache();
view.setDrawingCacheEnabled(true);
Bitmap cache = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
ImageView iv = new ImageView(this);
iv.setImageBitmap(cache);
return iv;
}


List<NewsTitle> mAlist = new ArrayList<NewsTitle>();


private void getAllList() {
mAlist.clear();
List<NewsTitle> mList = userAdapter.getChannnelLst();
List<NewsTitle> mOtherList = otherAdapter.getChannnelLst();
for (int i = 0; i < mList.size(); i++) {
NewsTitle mUsers = mList.get(i);
mUsers.titleSelected = 1;
mUsers.titleOrderId = i;
mAlist.add(mUsers);
}
for (int i = 0; i < mOtherList.size(); i++) {
NewsTitle mOther = mOtherList.get(i);
mOther.titleSelected = 0;
mAlist.add(mOther);
}
}


/** 退出时候保存选择后数据库的设置 */
private void saveChannel() {
getAllList();
long s = mNewsTitleTable.insertorUpdateUserMsg(mAlist, MyApplication.getInstance());
if (s > 0) {
sendBroadcast(new Intent(UPDATEBROADCAST));
}
}


@Override
protected void onPause() {
super.onPause();
}


@Override
protected void onDestroy() {
// 移动或点击后,自动保存数据
if (userGridView.isMoveEd || isClick) {
saveChannel();
}
super.onDestroy();
}
private void initSlideBackClose() {
if (isSupportSwipeBack()) {
SlidingPaneLayout slidingPaneLayout = new SlidingPaneLayout(this);
// 通过反射改变mOverhangSize的值为0,
// 这个mOverhangSize值为菜单到右边屏幕的最短距离,
// 默认是32dp,现在给它改成0
try {
Field overhangSize = SlidingPaneLayout.class
.getDeclaredField("mOverhangSize");
overhangSize.setAccessible(true);
overhangSize.set(slidingPaneLayout, 0);
} catch (Exception e) {
e.printStackTrace();
}
slidingPaneLayout.setPanelSlideListener(this);
slidingPaneLayout.setSliderFadeColor(getResources().getColor(
android.R.color.transparent));


// 左侧的透明视图
View leftView = new View(this);
leftView.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
slidingPaneLayout.addView(leftView, 0);


ViewGroup decorView = (ViewGroup) getWindow().getDecorView();


// 右侧的内容视图
ViewGroup decorChild = (ViewGroup) decorView.getChildAt(0);
decorChild.setBackgroundColor(getResources().getColor(
android.R.color.white));
decorView.removeView(decorChild);
decorView.addView(slidingPaneLayout);


// 为 SlidingPaneLayout 添加内容视图
slidingPaneLayout.addView(decorChild, 1);
}
}


protected boolean isSupportSwipeBack() {
return true;
}


@Override
public void onPanelClosed(View arg0) {


}


@Override
public void onPanelOpened(View arg0) {
finish();
}


@Override
public void onPanelSlide(View arg0, float arg1) {


}


}

一下为网络主框架类

package com.my.li.funny.notework;


import java.util.LinkedList;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;


import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;


import android.text.TextUtils;


import com.my.li.funny.MyApplication;
import com.my.li.funny.tools.ConstData;


public class LoadDataManager {
// 线程池开启线程个数
private static int MAX_HTTP_THREAD_COUNT = 4;


// jsoup超时时间为20s
private final static int JSOUPTIMEOUT = 22000;


private static ExecutorService ThreadPool = Executors.newFixedThreadPool(
MAX_HTTP_THREAD_COUNT, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
AtomicInteger ints = new AtomicInteger(0);
return new Thread(r, "httpThreadPool#"
+ ints.getAndIncrement());
}
});


private static LinkedList<DataAsynTask> dataAsynTasks = new LinkedList<>();


public static void cancelAllThread() {
for (int i = 0; i < dataAsynTasks.size(); i++) {
dataAsynTasks.get(i).cancel();
}
dataAsynTasks.clear();
}


public static void remove() {
dataAsynTasks.clear();
}


/**
* 一般的接口请求

* @param isPost是否是post方式
* @param urlName接口url
* @param postStrOther
*             post请求参数
* @param cb
*            请求回调
*/
public static void executeTask(String urlName, final IHttpCallBack cb) {
try {
if (!ConstData.checkNetState(MyApplication.getInstance())) {
MyApplication.getInstance().getMainHandler()
.post(new Runnable() {
@Override
public void run() {
cb.onFail("no aviliable network");
}
});
return;
}
DataAsynTask task = new DataAsynTask();
task.executeOnExecutor(cb, urlName, ThreadPool);
dataAsynTasks.add(task);
} catch (Exception e) {
e.printStackTrace();
ThreadPool.shutdownNow();
}
}


private static class DataAsynTask {
private TaskThread task;


public void cancel() {
if (task != null) {
try {
task.cancel();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}


public void executeOnExecutor(IHttpCallBack callBack, String loadUrl,
Executor executor) {
task = new TaskThread(callBack, loadUrl);
task.setName(loadUrl);
if (executor != null) {
executor.execute(task);
} else {
task.start();
}
}


static class TaskThread extends Thread implements Runnable {
// public Context context = null;
public IHttpCallBack callBack = null;
// private LoadingDialog mLoading_dialog = null;
private int flag = 0;
// public boolean isShowDialog = true;
public String loadUrl;
private String result = "";


public void cancel() {
interrupt();
synchronized (callBack) {
callBack = null;
}
}


public TaskThread(IHttpCallBack callBack, String loadUrl) {
this.callBack = callBack;
this.loadUrl = loadUrl;
}


@Override
public void run() {
try {
if (!TextUtils.isEmpty(loadUrl)) {
// long time = System.currentTimeMillis();
System.setProperty("http.keepAlive", "true");
Connection mConnection = Jsoup.connect(loadUrl);
// 设置平台浏览器代理
mConnection
.userAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36");
// 设置超时时间
mConnection.timeout(JSOUPTIMEOUT);
Document mDoc = mConnection.get();
result = mDoc.toString();
if (!TextUtils.isEmpty(result)) {
flag = 0;
}
} else {
flag = -1;
}
} catch (Exception e) {
// System.setProperty("http.keepAlive", "false");
flag = -1;
ThreadPool.shutdownNow();
e.printStackTrace();
}
try {
if (flag == 0) {
MyApplication.getInstance().getMainHandler()
.post(new Runnable() {
@Override
public void run() {
if (callBack != null) {
callBack.onSuccess(result);
}
}
});
} else {
MyApplication.getInstance().getMainHandler()
.post(new Runnable() {
@Override
public void run() {
if (callBack != null) {
callBack.onFail(result);
}
}
});
}


} catch (Exception e) {
ThreadPool.shutdownNow();
e.printStackTrace();
} finally {


}
}
}
}


// private static class DataTask extends AsyncTask<String, Integer, String>
// {
// public Context context = null;
// public IHttpCallBack callBack = null;
// private LoadingDialog mLoading_dialog = null;
// private int flag = 0;
// public boolean isShowDialog = true;
// public String loadUrl;
//
// public void cancel() {
// if (task != null) {
// try {
// if(filterCancel(task))
// task.cancel();
// } catch (Exception ex) {
//
// }
// }
// }
//
// @Override
// protected void onPreExecute() {
// if (isShowDialog) {
// if (context != null) {
// try {
// if (null == mLoading_dialog)
// mLoading_dialog = new LoadingDialog(context,
// R.style.Dialog_Fullscreen, "");
// mLoading_dialog.show();
// } catch (Exception e) {
// e.printStackTrace();
// }
//
// }
// }
// }
//
// @Override
// protected void onProgressUpdate(Integer... values) {
// // 更新进度
//
// }
//
// @Override
// protected String doInBackground(String... params) {
// String result = "";
// try {
// if (!TextUtils.isEmpty(loadUrl)) {
// long time = System.currentTimeMillis();
// System.setProperty("http.keepAlive", "true");
// Connection mConnection = Jsoup.connect(loadUrl);
// // 设置平台浏览器代理
// mConnection
// .userAgent("Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36");
// // 设置超时时间
// mConnection.timeout(JSOUPTIMEOUT);
// // Response mResponse = mConnection.execute();
// // 获取数据
// // mConnection.method(Method.POST);
// // Document mDoc =mResponse.parse();
// Document mDoc = mConnection.get();
// result = mDoc.toString();
// Log.e("lwwqiao",
// "-----获取数据时间 ----"
// + (System.currentTimeMillis() - time));
// // 方法二
// // URL url = new URL(loadUrl);
// // URLConnection ucon = url.openConnection();
// // InputStream instr = ucon.getInputStream();
// // BufferedInputStream bis = new BufferedInputStream(instr);
// // ByteArrayBuffer baf = new ByteArrayBuffer(1024);
// // int current = 0;
// // bis.skip(11000);
// // while ((current = bis.read()) != -1) {
// // baf.append((byte) current);
// // }
// // // result =new String(baf.toByteArray(),0,baf.length());
// // result = EncodingUtils.getString(baf.toByteArray(), 0,
// // baf.length(), "utf-8");
// // instr.close();
// // bis.close();
// // baf.clear();
// // baf = null;
// // instr = null;
// // bis = null;
//
// // 关闭连接
// } else {
// return "url is null";
// }
// } catch (Exception e) {
// // System.setProperty("http.keepAlive", "false");
// flag = -1;
// ThreadPool.shutdownNow();
// this.cancel(true);
// e.printStackTrace();
// return "connection error" + e.getMessage();
// }
// flag = 0;
// return result;
// }
//
// @Override
// protected void onCancelled() {
// super.onCancelled();
// if (mLoading_dialog != null) {
// mLoading_dialog.dismiss();
// }
// if (callBack != null)
// callBack.onCancel();
// }
//
// @SuppressLint("NewApi")
// @Override
// protected void onCancelled(String result) {
// super.onCancelled(result);
// if (mLoading_dialog != null) {
// mLoading_dialog.dismiss();
// }
// if (callBack != null)
// callBack.onCancel();
// }
//
// @Override
// protected void onPostExecute(String r) {
// if (callBack != null) {
// if (flag == 0) {
// callBack.onSuccess(r);
// } else {
// String errorString = null;
// if (null == r) {
// errorString = "empty url or empty object ";
// } else {
// errorString = r;
// }
// callBack.onFail(errorString);
// }
// }
// if (mLoading_dialog != null) {
// mLoading_dialog.dismiss();
// }
// }
// }


}


// 解析糗事百科首页数据
public static List<FunyEntity> getPseronfunPageParseHTML(String mHtml) {
if (null == mHtml) {
return null;
}
List<FunyEntity> mFunArray = new ArrayList<FunyEntity>();
FunyEntity mFunyEntity;


final Document doc = Jsoup.parse(mHtml);
if (null == doc) {
return null;
}
Elements mAllData = doc.select("div.article");


for (int i = 0; i < mAllData.size(); i++) {
Element mElement = mAllData.get(i);
Element mContent = mElement.select("div.content").first();
Element icon = mElement.select("div.thumb").first();
Element userMessage = mElement.select("div.author").first();


mFunyEntity = new FunyEntity();
// /内容类型
if (null != mContent) {
Element spanElement = mContent.select("span").first();
if (null != spanElement) {
mFunyEntity.funyContent = spanElement.text();
}
}
// 图片类型
if (null != icon) {
Element imageIcon = icon.getElementsByTag("img").first();
if (null != imageIcon) {
String imagePath = imageIcon.attr("src");
if (!TextUtils.isEmpty(imagePath)) {
mFunyEntity.imagerUrl = "https:" + imagePath;
} else {
mFunyEntity.imagerUrl = MyApplication.getInstance()
.setIconPath();
}
} else {
mFunyEntity.imagerUrl = MyApplication.getInstance()
.setIconPath();
}
} else {
mFunyEntity.imagerUrl = MyApplication.getInstance()
.setIconPath();
}
// 用户信息
if (null != userMessage) {
Element imageIcon = userMessage.getElementsByTag("img").first();
if (null != imageIcon) {
mFunyEntity.userIcon = "https:" + imageIcon.attr("src");
mFunyEntity.userName = imageIcon.attr("alt");
// Log.e("lwwqiao", "用户"+mFunyEntity.userName);
}
}
if (!TextUtils.isEmpty(mFunyEntity.funyContent)
|| !TextUtils.isEmpty(mFunyEntity.imagerUrl)) {
// 若图片或者文字不为空,则获取图片或文字的详情连接并添加数据。
Element link = mElement.select("a.contentHerf").first();
if (null != link) {
String relHref = link.attr("href");
if (!TextUtils.isEmpty(relHref)) {
mFunyEntity.detailUrl = LinkUrl.QIUBAIMANURL + relHref;
// Log.e("lwwqiao", "详情"+mFunyEntity.detailUrl);
}
}
mFunArray.add(mFunyEntity);
}
}
return mFunArray;


}

不废话了,直接上图片



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值