一.圖靈機器人的編寫需要用到的知識以及工具
(1)本次程序編寫用到的是android studio
(2)要完成圖靈機器人最基本的操作就是獲得機器人對於你所發的消息進行返回的消息,首先要獲取圖靈機器人的api接口,這部分內容可以在http://www.tuling123.com/上面註冊一個賬號,然後登陸,點擊之以下界面,其中的apikey是你即將要記得的東西,對於api的操作可以參考文檔(基本的原理是:通過訪問一個網頁http://www.tuling123.com/+apikey&info="你所輸入的信息" 例如:http://www.tuling123.com/http://www.tuling123.com/openapi/api?key=44ae440524f4daf68195953f180add0d&info=%E4%BD%A0%E5%A5%BD,就可以得到一串簡單的json數據);
(3)如果你通過訪問上面的網址看到了一串json數據,那麼接下來必不可少的肯定要解析這串數據,所以要用到json數據的解析;
(4)其他的就是listview,adapter的運用以及數據的封裝等等。
二.圖靈機器人的編寫思路(主要通過幾個類來呈現)
1.數據:首先處理一系列的數據
(1)httpdata類
//下面3個參數:1.表示傳入的值是String 2.表示進度爲空 3.表示返回的值爲String public class HttpData extends AsyncTask<String,Void,String> { private String website; private HttpURLConnection connection; private InputStream in; private BufferedReader reader; private HttpCallbackListener listener; public HttpData(String website,HttpCallbackListener listener) { this.website=website; this.listener=listener; } @Override protected String doInBackground(String... params) { try { URL url = new URL(website); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); in = connection.getInputStream(); StringBuffer sb = new StringBuffer(); reader = new BufferedReader(new InputStreamReader(in)); String line; while ((line=reader.readLine())!=null) { sb.append(line); } return sb.toString(); } catch (Exception e) { e.printStackTrace(); } return null; } //下面的String s是返回的結果 @Override protected void onPostExecute(String s) { listener.getData(s); super.onPostExecute(s); } }
大體思路:通過調用這個類中的函數,來返回一段json數據(即訪問網址得到的字符串)
細節:此類繼承了AsyncTask抽象類(這個類是android中封裝的很好的異步消息處理機制,及在子線程中可以很方便的切換到UI線程),在這裏需要重寫兩個方法
doInBackground和onPostExcute,第一個方法是子線程所做的操作都在這裏完成,在這裏我們可以
進行訪問服務器(輸入網址得到json數據)的操作(這個操作需要用到httpURLConnection),數據
返回到第二個方法中的參數當中,在第二個方法中我們注意到getData這個方法,這個方法是
HttpCallbackListener listener這個接口中的方法,即需要實現這個方法,那麼這個方法其實就
是用來解析json數據的(其實我一開始的做法是沒有用到AsyncTask,而是直接通過在子線程中獲取
數據後返回,但是這樣怎麼也不行,即返回的數據老是空,這部分還是沒有明白)。
(2)ListData類
public class ListData {
private String content;
private int flag;
public final static int SEND=0;
public final static int RECEIVE=1;
private String time;
public ListData(String content,int flag,String time)
{
this.content=content;
this.flag=flag;
this.time=time;
}
public String getContent()
{
return content;
}
public int getFlag()
{
return flag;
}
public String getTime()
{
return time;
}
}
這個類是很重要的類,但是很簡單,這個就是前面說的數據封裝,我們一起來看這個類當中就只有content,flag兩個
重要的屬性,content是聊天時雙方所發送的內容,既然是雙方,那麼肯定要有個標誌位flag;其中的time屬性是代表
時間(簡單的說一下,這個屬性是用來表示當雙方聊天時間間隔超過n秒時需要在頻幕上顯示當前的時間的);那麼這
個類其實只是封裝了一條信息,即只能表示發送或者接受的一條基本信息,我們需要一個更大的盒子來承載,(就像
數組承載了其他基本類型一樣,我們需要某個東西來承載類,那麼我們自然而然就想到了List<E>),所以所有的數據
都被統一封裝到lists當中,這樣程序實現所有需要的數據都已經準備好
2.界面:主要部分是ListView
(1)這裏聊天只涉及到一個界面,因此只需要一個活動
public class MainActivity extends Activity implements HttpCallbackListener{ private String website; private HttpData httpData; private HttpCallbackListener hp; private String returnData; private String changeCode; private List<ListData> lists; private ListView lv; private EditText et; private Button bt; private TextAdapter adapter; private String welcomeArray[]; private double currentTime,oldTime=0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); bt=(Button) findViewById(R.id.button); bt.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String s=et.getText().toString(); ChangeCode(s); ListData listData=new ListData(s,ListData.SEND,getTime()); lists.add(listData); adapter.notifyDataSetChanged(); website="http://www.tuling123.com/openapi/api?key=44ae440524f4daf68195953f180add0d&info="+changeCode; Log.e("haha",website); httpData= (HttpData) new HttpData(website,MainActivity.this).execute(); et.setText(""); } }); // Log.e("haha",returnData); } private String getTime() { currentTime=System.currentTimeMillis(); String currentDate; SimpleDateFormat format=new SimpleDateFormat("yyyy年mm月dd日 HH:mm:ss"); Date date=new Date(); currentDate=format.format(date); if(currentTime-oldTime>=60*1000) { oldTime=currentTime; return currentDate; } else { return ""; } } private String getWelcomeTips() { String welcomeTip; welcomeArray=this.getResources().getStringArray(R.array.welcome_tips); int index= (int) (Math.random()*(welcomeArray.length-1)); //Toast.makeText(this,index,Toast.LENGTH_SHORT).show(); welcomeTip=welcomeArray[index]; return welcomeTip; } private void ChangeCode(String testCode) { // String testCode="你好"; try { changeCode = URLEncoder.encode(testCode, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } private void initView() { lists=new ArrayList<ListData>(); lv=(ListView) findViewById(R.id.lv); et=(EditText) findViewById(R.id.editText); adapter=new TextAdapter(lists,this); lv.setAdapter(adapter); ListData listData=new ListData(getWelcomeTips(),ListData.RECEIVE,getTime()); lists.add(listData); } @Override public void getData(String s) { parseText(s); } private void parseText(String s) { try { JSONObject jsonObject = new JSONObject(s); ListData listData=new ListData(jsonObject.getString("text"),ListData.RECEIVE,getTime()); lists.add(listData); adapter.notifyDataSetChanged(); } catch (Exception e) { e.printStackTrace(); } } }
(2)界面主要採用ListView以及下部的輸入框和提交按鈕,而在此我們需要顯示的最基本的有人物和機器人的頭像(ImageView)和雙方所說的話
(TextView)以及一些附加的顯示時間。上面說的是ListView的每一條基本元素需要包括這些。
(3)那麼我們自然而然想到用adapter來進行界面與數據的適配,這裏我用的是BaseAdapter,這部分代碼不需要過多解
釋。
(4)其中一些歡迎語(對應的函數是getWelcomeTips)等等都是一些比較簡單的代碼。
三.最後
(1)說說我寫這篇博客的感受,感覺自己思路還不是很清晰,很多東西我不能用專業化
的語句寫出來,還有就是感覺上面的代碼貼的很醜(畢竟標準理科生,毫無審美),
所以後面的代碼我沒有貼出來,我覺得還是發個百度雲盤鏈接比較好
鏈接:http://pan.baidu.com/s/1nvQxTpR 密碼:9yjb
(2)說說我寫這個程序的感受,寫這個程序給我最大的啓發就是數據的封裝以及接口的
靈活使用,然後還有就是listview用法的進一步熟悉還有等等。