1.向第三方API发起请求,解析返回数据
public class HttpUtil {
public static ChatMessage sendMessage(String msg) {
ChatMessage message = new ChatMessage();
String jsonStr = doGet(msg);
Gson gson = new Gson();
try {
//gson解析XML,转成对象,需要gson.jar包
Result result = gson.fromJson(jsonStr, Result.class);
message.setMsg(result.getText());
} catch (JsonSyntaxException e) {
message.setMsg("服务器繁忙,请稍后再试。");
}
message.setDate(new Date());
message.setType(Type.ANSWER);
return message;
}
public static String doGet(String msg) {
String url = "";
String result = "";
try {
url = "http://www.tuling123.com/openapi/api?key=87f43665ef51fe960fd4d3950ec021ad&info="
+ URLEncoder.encode(msg, "utf-8");
} catch (Exception e) {
e.printStackTrace();
}
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
URL urlNet = new URL(url);// 获得url地址
HttpURLConnection conn = (HttpURLConnection) urlNet
.openConnection();// 通过url获得连接
conn.setReadTimeout(3000);// 设置读数据的时限
conn.setConnectTimeout(3000);// 设置连接时限
conn.setRequestMethod("GET");// 设置请求连接方式
is = conn.getInputStream();
baos = new ByteArrayOutputStream();
int len = -1;
byte[] buf = new byte[128];
while ((len = is.read(buf)) != -1) {
baos.write(buf, 0, len);
}
result = new String(baos.toByteArray());
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (baos != null) {
baos.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
}
2.listview+adapter+数据源
public class ChatMessageAdapter extends BaseAdapter {
private LayoutInflater mInflater;// 布局压榨器,需要上下文对象来获得
private List<ChatMessage> mData;
//从activity中传来的context,数据源来初始化这两个必备成员变量
public ChatMessageAdapter(Context context, List<ChatMessage> mData) {
mInflater = LayoutInflater.from(context);
this.mData = mData;
}
// 集合的总个数
@Override
public int getCount() {
return mData.size();
}
// 获取mData中的对象
@Override
public Object getItem(int pos) {
return mData.get(pos);
}
// mData中对象的下标
@Override
public long getItemId(int pos) {
return pos;
}
////////////////////////////////////////////////////////
这两个方法是listview中有两种/两种以上的item时,用到的
@Override
public int getViewTypeCount() {
return 2;
}
@Override
public int getItemViewType(int pos) {
return mData.get(pos).getType() == Type.ANSWER ? 0 : 1;
}
////////////////////////////////////////////////////////
@Override
public View getView(int pos, View view, ViewGroup parent) {
ChatMessage message = mData.get(pos);
ViewHolder holder = null;// 布局中要更改的值
if (view == null) {// 当view为空时,创建view
holder = new ViewHolder();
// 通过ItemType
if (getItemViewType(pos) == 0) {
//把XML压成布局
view = mInflater.inflate(R.layout.layout_answer, parent, false);
holder.mDate = (TextView) view
.findViewById(R.id.tv_answer_date);
holder.mMsg = (TextView) view.findViewById(R.id.tv_answer_msg);
} else {
view = mInflater.inflate(R.layout.layout_send, parent, false);
holder.mDate = (TextView) view.findViewById(R.id.tv_send_date);
holder.mMsg = (TextView) view.findViewById(R.id.tv_send_msg);
}
view.setTag(holder);//给view设置tag,
} else {
holder = (ViewHolder) view.getTag();//从view中得到,tag
}
// 设置数据,时间的处理!!!!! 积累呀!!!
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
holder.mDate.setText(sdf.format(message.getDate()));
holder.mMsg.setText(message.getMsg());
return view;
}
// 布局中要修改的值,建立一个对象
private final class ViewHolder {
TextView mDate;
TextView mMsg;
}
}
3.activity中的写法
public class MainActivity extends Activity {
// 适配器的三个必备,ListView/adapter/lists
private ListView mLvMsgs;
private ChatMessageAdapter mAdapter;
private List<ChatMessage> mDatas;
private EditText mEtInput;
private Button mBtnSend;
// 等待接收,子线程完成数据的返回
//把线程中的要处理的东西放到handler中,分离声明和处理
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
ChatMessage message = (ChatMessage) msg.obj;
mDatas.add(message);
mAdapter.notifyDataSetChanged();//通知adapter更新!!!
mLvMsgs.setSelection(mDatas.size() - 1);// 最后一个被选中
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
inti();
initDatas();
registeListener();
}
private void registeListener() {
mBtnSend.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final String sendMsg = mEtInput.getText().toString();
if (TextUtils.isEmpty(sendMsg)) {
Toast.makeText(MainActivity.this, "消息不能为空",
Toast.LENGTH_SHORT).show();
return;
}
ChatMessage sendMessage = new ChatMessage(sendMsg, Type.SEND,
new Date());
mDatas.add(sendMessage);
mAdapter.notifyDataSetChanged();
mLvMsgs.setSelection(mDatas.size() - 1);
mEtInput.setText("");
new Thread() {
public void run() {
ChatMessage answerMessage = HttpUtil
.sendMessage(sendMsg);
Message m = Message.obtain();//Handler处理的Message的对象,静态方法获得
m.obj = answerMessage;//把要处理的对象装到message的obj中
// 创建线程和处理分开
mHandler.sendMessage(m);//交给Handler处理
}
}.start();
}
});
}
public void inti() {
mLvMsgs = (ListView) findViewById(R.id.lv_main);
mEtInput = (EditText) findViewById(R.id.et_input);
mBtnSend = (Button) findViewById(R.id.btn_send);
}
public void initDatas() {
mDatas = new ArrayList<ChatMessage>();
mDatas.add(new ChatMessage("你好,小慕为您服务", Type.ANSWER, new Date()));
mAdapter = new ChatMessageAdapter(this, mDatas);
mLvMsgs.setAdapter(mAdapter);//为listview绑定适配器
}
}
4.单独说一下{(把XML转成对象,XML中结点的名字要与对象成员变量的名字一样,利用gson.jar包),
(java中的enum,枚举类型
public enum Type {
SEND, ANSWER
}
在没有枚举类型之前,我们定义常量都是public static final ...,比较不方便,是同一类型的,却还要单独定义....
有了enum就好了,可以定义在一个枚举类型中了。注意!!! 如上,SEND和ANSWER并不像是C/C++中是从0开始的,它就是它自己!
更详细的可以参考:http://www.cnblogs.com/happyPawpaw/archive/2013/04/09/3009553.html
)}