这一系列文章的目的是以单个需求为向导,十分钟左右能完成的Android范例编程。
生活中避免不了要查单词,自己写一个也是很简单的事情。效果如下:



安卓系统背单词软件的架构 android背单词源代码_Android

 



本篇主要涉及了Android中的多线程以及一个开源库JSOUP的使用。

  首先创建项目

 在项目的 在项目模块的build.gradle中 dependencies节点块中 添加引用 compile 'org.jsoup:jsoup:1.8.3',JSOUP是一个开源的HTML文档解析库,可以从网址,字符串中解析HTML文档,抽取相关内容,语法类似于JS中的选择器,支持元素、类、ID的的DOM内容抽取。

 在布局文件中 在顶部添加一个EditView,一个Button,做为查询 再依次添加四个TextView,显示对应的单词,音标,解释,来源,如下图:



安卓系统背单词软件的架构 android背单词源代码_Android_02




打开网页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解析器,甚至可以用来在手机上制作爬虫。