这一系列文章的目的是以单个需求为向导,十分钟左右能完成的Android范例编程。
生活中避免不了要查单词,自己写一个也是很简单的事情。效果如下:
本篇主要涉及了Android中的多线程以及一个开源库JSOUP的使用。
首先创建项目
在项目的 在项目模块的build.gradle中 dependencies节点块中 添加引用 compile 'org.jsoup:jsoup:1.8.3',JSOUP是一个开源的HTML文档解析库,可以从网址,字符串中解析HTML文档,抽取相关内容,语法类似于JS中的选择器,支持元素、类、ID的的DOM内容抽取。
在布局文件中 在顶部添加一个EditView,一个Button,做为查询 再依次添加四个TextView,显示对应的单词,音标,解释,来源,如下图:
打开网页http://dict.youdao.com/search?q=love,查看源码,可以看到对应的音标CSS类为“phonetic” 对应的解释类为trans-container,OK,信息足够了,可以开始写业务代码了,流程如下
输入单词,从网址中获取对应的HTML文档,解析文档,得到音标和释义。Android中对网络的操作必须在子线程中进行,避免ANR(应用程序无响应),这里把业务代码放在AsyncTask中,在Activity中新建一个内部类,继承AsyncTask,重写
doInBackground 方法,这个方法是工作在子线程中的,从网站获取音标和解释。
再重写 onPreExecute
onPostExecute方法,这是工作在UI线程中的,分别在
doInBackground之前和之后执行。
class WordTask extends AsyncTask{
private String url = "http://dict.youdao.com/search?q=";
private Document doc;
private String word;
private String phonetic = "获取失败";
private String trans = "获取失败";
private String source = "有道词典";
public WordTask(){
word = edit_word.getText().toString();
url = url+ word;
}
@Override
protected Object doInBackground(Object[] params) {
try {
doc = Jsoup.connect(url).timeout(3000).get();
phonetic = doc.select(".phonetic")
.first().text();
trans = doc.select(".trans-container")
.first().text();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPreExecute() {
dialog.show();
super.onPreExecute();
}
@Override
protected void onPostExecute(Object o) {
tv_word.setText(word);
tv_phonetic.setText(phonetic);
tv_trans.setText(trans);
tv_source.setText(source);
dialog.dismiss();
super.onPostExecute(o);
}
}
Activity的OnCreate方法和Button设置监听器
private EditText
edit_word
;
private TextView
tv_word
; private
TextView
tv_phonetic
;
private TextView
tv_trans
; private
TextView
tv_source
;
private ProgressDialog
dialog
;
@Override
protected void onCreate
(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState)
;
setContentView(R.layout.
activity_main
)
;
edit_word
= (EditText) findViewById(R.id.
edit_word
)
;
tv_word
= (TextView) findViewById(R.id.
tv_word
)
;
tv_phonetic
= (TextView) findViewById(R.id.
tv_phonetic
)
;
tv_trans
= (TextView) findViewById(R.id.
tv_trans
)
;
tv_source
= (TextView) findViewById(R.id.
tv_source
)
;
dialog
=
new
ProgressDialog(
this
)
;
dialog
.setTitle(
"
正在查询
"
)
;
findViewById(R.id.
button_search
).setOnClickListener(
new
View.OnClickListener() {
@Override
public void
onClick
(View v) {
if
(TextUtils.
isEmpty
(
edit_word
.getText().toString())){
Toast. makeText
(MainActivity.
this,
"
请填写要查询的单词
"
,
Toast.
LENGTH_SHORT
).show()
;
return;
}
InputMethodManager imm = (InputMethodManager)
getSystemService(MainActivity. this
.
INPUT_METHOD_SERVICE
)
;
imm.toggleSoftInput(
0
,
InputMethodManager.
HIDE_NOT_ALWAYS
)
;
WordTask task =
new
WordTask()
;
task.execute()
;
}
}) ;
}
仍然不到一百行,一个完整可用的生词查询就完成了。
为了控制时间,查询后的单词存入数据库,以及生词本的制作放在接下来的两篇中。
完整代码
git clone https://github.com/songgois/androidWords.git
一句话知识点:
- gradle是Android Studio中的一个项目自动化构建工具,可轻松解决依赖、多渠道打包等问题,是一种动态语言,运行在JVM上。
- Android中主线程为UI线程,不应该在UI线程中进行耗时操作。
- AsyncTask是Android框架中的一个轻量线程池,实际业务过程中使用较小,因为控制不好可能引起内存泄露。
- JSOUP是java常用的HTML解析器,甚至可以用来在手机上制作爬虫。