WEBAPP开发教程Android原始应用与web app集成:内嵌jquery mobile为html5框架
凌雪 2018-10-11 来源 :网络 阅读 1833 评论 0

摘要:本文将带你了解WEBAPP开发教程Android原始应用与web app集成:内嵌jquery mobile为html5框架,希望本文对大家学WEBAPP有所帮助。

本文将带你了解WEBAPP开发教程Android原始应用与web app集成:内嵌jquery mobile为html5框架,希望本文对大家学WEBAPP有所帮助。


前言:
   
       很长时间一直思考什么时候需要原生应用于html5开发的web   app结合去开发一个App;终于做了一个《立波育儿百科》的应用,才尝试了这种方式做一个App;
   
    本文作者:心有灵犀鬼才心,blog地址://blog.csdn.net/changemyself     ,微博地址://weibo.com/changeself
   
    如要转载本文,请加上本文地址和作者名称,不得删除原文链接;
   
   
   
   
    项目介绍:
   
    这是   一个百科类的App,主要包含了育儿、养生、怀孕、饮食、母婴用品等方面的资料,这些资料有个特点,都是html格式,采用CSS将其分段存储在数据库里;
   
    考虑到要做一个Android版本和Ios版本,所以尽量让网页内容得以在2个系统上共享,维护一份网页内容,使其在2个手机平台上使用;
   
    在App的操作使用方面,主界面就是百科分类,然后用户进入分类就显示该分类下的标签项,用户通过标签项来进一步找到自己要看的百科文章;当然还有“文章收藏”和“文章搜索”的功能。
   
    如图所示:
   
   
   
   
   
   
   
    在文章页面展示上,采用了jquery   mobile的UI风格:页面标题栏+内容栏,用户点击页面,会使页面标题栏会自动隐藏/显示,如果页面展示超过一屏,我在页面最右下角加了一个“回到顶部”的快捷方式;当然页面标题栏还有“返回”和“收藏”的2个按钮,分别帮助用户能够返回上一级的页面,收藏当前喜欢关注的文章。
   
    如图所示:
   
   
   
   
   
   
   
   
   
    原生和html5的交互界面介绍:
   
    这个是本文的重点,
   
    准备工作:首先我是用python和django template技术奖数据库的内容按照jquery   ui做成的模板批量生成了静态html页面,大概20多M吧,我都直接扔到/asset目录下,好让webview加载使用。
   
   
   
   
    代码设计:加载html5网页的webview会单独嵌入在一个Activity,我们称之为WebPageActivity;
   
    我们还要增加一个类ActionHelper专门负责原生程序和JS直接的通信,包含以下功能:添加收藏,设置页面标题,关闭当前Activity
   
   
   
   
   
    [java] view
     plaincopyprint?
   
   
   
   
   
   
    package com.souapp.baike.yuer.js;  
      
    import android.app.Activity;  
    import android.os.Handler;  
    import android.util.Log;  
    import android.webkit.WebView;  
      
    import com.souapp.baike.yuer.db.DBFavoriteOpeator;  
      import com.souapp.baike.yuer.exception.DataIsExistException;  
    import com.souapp.baike.yuer.favorite.FavoriteBean;  
    import com.souapp.common.tools.DateTools;  
      
    /**** 
     * 处理JS主动调用自己的方法 
     * @author Tester 
     * 
     */  
    public class ActionHelper {  
          private String TAG="ActionHelper";  
        private Activity cxt;  
        private WebView webview;  
          private String callbackFunction;//条码扫描结果,给JS的回调函数  
        private ActionHelper(){}  
        private static  ActionHelper instance;  
          private Handler handler;  
          private String result="添加收藏成功.";  
          
          public static ActionHelper getInstance(){  
              if (instance==null){  
                instance=new ActionHelper();  
            }  
              return instance;  
        }  
          public void setValue(Activity context,WebView wv,Handler ha){  
              cxt=context;  
            webview=wv;  
              handler=ha;  
        }  
          
          
        /*** 
         * 把扫码结果回调给JS 
         * @param data 
         */  
        public void saveBarcodeScanData(String data){  
            try{  
                  webview.loadUrl("javascript:"+callbackFunction+"('"+data+"')");  
              }catch(Exception e){  
                Log.e(TAG, "",e);  
            }  
        }  
        /*** 
         * 设置页面标题 
         * @param name 
         */  
          public void setBaikeTitle(final String name){  
            try{  
      
                  handler.post(new Runnable() {    
                        
                      public void run() {    
                          //调用客户端setContactInfo方法    
                        webview.loadUrl("javascript:setBaikeTitle('"+name+"')");  
                      }    
                  });   
                    
                  
              }catch(Exception e){  
                  Log.e(TAG, "",e);  
            }  
        }  
          
        /*** 
         * 搜索页面里调用查看本地详细文章 
         * @param savepath 
         */  
        public void viewDetail(final String savepath){  
            try{  
                    
                Log.d(TAG, "=========viewDetail=========");  
      
              }catch(Exception e){  
                Log.e(TAG, "",e);  
            }finally{  
                      handler.post(new Runnable() {    
                          
                    public void run() {    
                          //调用JS,显示操作状态  
                          webview.loadUrl("file:///android_asset/static_mobile_baike"+savepath);  
                    }    
                  });  
            }  
        }  
          
          
        /*** 
         * 把文章加入收藏夹里 
         * @param name 
         */  
          public void addFavorite(final String title,final String category,final String tag,final String savepath){  
              
            try{  
                  
                  Log.d(TAG, "=========addFavorite=========");  
                String savedate=DateTools.formatLong2Str(System.currentTimeMillis());  
                  FavoriteBean bean=new FavoriteBean();  
                  bean.setTitle(title);  
                  bean.setCategory(category);  
                bean.setTag(tag);  
                  bean.setSavepath(savepath.substring(1));  
                bean.setOrder(0);  
                  bean.setSavedate(savedate);  
                  
                  DBFavoriteOpeator.saveFavorite(cxt,bean);  
                  
                  result="成功添加到收藏夹";  
              }catch(DataIsExistException e1){  
                Log.e(TAG, "",e1);  
                  result="提示:"+e1.getMessage();  
                    
                    
            }catch(Exception e){  
                  Log.e(TAG, "",e);  
                  result="错误:"+e.getMessage();  
            }finally{  
                      handler.post(new Runnable() {    
                          
                      public void run() {    
                          //调用JS,显示操作状态  
                        webview.loadUrl("javascript:callBack_echoMsg('"+result+"')");  
                    }    
                  });  
            }  
        }  
          
        /**** 
         * JS调用关闭Activity 
         * @param mother 
         */  
          public  void exitActivity(){  
            try{  
                if (cxt==null) return;  
                  cxt.finish();  
              }catch(Exception e){  
                  e.printStackTrace();  
            }  
        }  
      
        /**** 
         * 调用条码扫描界面 
         */  
          public void startBarCodeScanUI(String url,String invokeFunction){  
    /*      try{ 
                  Log.e(TAG, " start url:"+url); 
                callbackFunction=invokeFunction; 
                   
                Intent it=new Intent(); 
                  it.setClass(cxt, ZXingScannerActivity.class); 
                it.putExtra("queryUrl", url);//把请求的URl传给扫码的页面 
                  cxt.startActivity(it); 
            }catch(Exception e){ 
                  e.printStackTrace(); 
            }*/  
        }  
    }  
   
   
   
   
   
   
   
   
   
      目录浏览:当用户点击主页面的某个分类(例如:育儿百科),我会通过webview去加载一个分类展示页面,然后用户在分类展示页面再点击操作,那就是通过html相对链接的方式在跳转了;在分类展示页面会有一个“返回主页面”的按钮,这个按钮是通过JS调用原生程序来控制关闭webview的Activity
   
   
   
   
      这个“返回主页面”是JS调用原生代码,那么还有一个操作是原生调用JS代码的地方:页面的标题,是根据主界面的分类传到WebPageActivtiy里然后显示在html5的页面上的。
   
    我们看代码如下:
   
    原生代码看上面ActionHelper.java里的setBaikeTitle方法,然后我们去看JS的代码如下:
   
   
   
   
    设置百科文章标题的JS代码:
   
   
   
   
   
    [javascript] view
     plaincopyprint?
   
   
   
   
   
   
    <script type="text/javascript">  
      
      
      function setBaikeTitle(name){  
          console.log("setTitle:"+name);  
        //$("#baike_title").html(name);  
          document.getElementById("baike_title").innerHTML=name;  
      
      }  
    </script>  
   
   
   
   
   
   
    关闭Activity的JS代码
   
   
   
    [javascript] view
     plaincopyprint?
   
   
   
   
   
   
    <script type="text/javascript">  
      
      
      //给按钮,绑定一个事件监听器  
        $(document).bind('pageinit', function() {  
      
      
            $('#goback').bind('tap', function(e) {  
                  
            //调用手机关闭主页面  
      
              if(window.es){  
                window.es.exitActivity();  
              console.log("关闭当前百科页面");  
                return;  
            }  
              
      
          });  
      });  
      
      
      
    </script>   
   
   
   
   
   
   
   
   
    这里的es是ActionHelper暴露给webview可以调用的对象看我在WebPageActivity里webview的定义代码:
   
   
   
   
   
    [java] view
     plaincopyprint?
   
   
   
   
   
   
      
   
   
   
   
    [java] view
     plaincopyprint?
   
   
   
   
   
   
      <span style="white-space:pre">      </span>WebView wv = (WebView) this.findViewById(R.id.webview);  
   
   
   
   
    [java] view
     plaincopyprint?
   
   
   
   
   
   
      <span style="white-space:pre">      </span>WebSettings settings = wv.getSettings();  
              settings.setJavaScriptEnabled(true);  
            settings.setAllowFileAccess(true);  
              wv.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);  
      
      
            SOUAPP_URL="file:///android_asset/static_mobile_baike/";  
              
              //先来判断是目录还是收藏的文章吧  
            String baike_article=getIntent().getExtras().getString("baike_article");  
              if(baike_article!=null){  
                //直接打开页面  
                  SOUAPP_URL+=baike_article+"?pageid=1";  
                Log.d(TAG, "页面:"+SOUAPP_URL);  
            }else{  
                  //走目录模式  
                  String baike_type=this.getIntent().getExtras().getString("baike_type");  
                SOUAPP_URL+=baike_type+".html";  
                    
                  baike_name=this.getIntent().getExtras().getString("baike_name");  
            }  
              
              
              /****把JS调用自己的方法注册***/  
              ah=ActionHelper.getInstance();  
            ah.setValue(this,wv,new Handler());  
              wv.addJavascriptInterface(ah, "es");  
            wv.loadUrl(S<span style="font-family: Arial, Helvetica, sans-serif;">OUAPP_URL</span>);  
              wv.setBackgroundColor(0);   
            wv.setBackgroundResource(R.drawable.loadpage);  
   
    这里呢,我省略了一些代码,例如:网页加载进度的显示的;
   
   
   
   
    看一下html5页面的代码:
   
   
   
   
   
    [html] view
     plaincopyprint?
   
   
   
   
   
   
    <!-- Home -->  
      <div data-role="page" id="main_page" data-dom-cache="true">  
      
      
      
      
          <div data-theme="a" data-role="header"   data-position="fixed" >  
            <a  id="goback" data-rel="back"   data-role="button"  data-icon="back">返回主页面</a>  
              <h3>  
                  <div id="baike_title">怀孕百科</div>  
            </h3>  
        </div>  
   
    id为goback就是返回按钮,id为baike_title,其innerHTML内容会被替换。
   
   
   
   
   
   
    这里不讲android webview如何与js进行通信,原理很简单大家如果不懂的话可以去查文章后再看本文。
   
   
   
   
    收藏夹浏览:
   
    这里面显示的都是用户收藏的百科文章,我使用sqllite数据库存在手机里;
   
   
   
   
    界面上“删除”操作是原生代码操作,点击每行就是查看文章页面操作,这个其实还是调用WebPageActivity去load在
   
   
   
    [java] view
     plaincopyprint?
   
   
   
   
   
   
    file:///android_asset/static_mobile_baike/    
   
   
   
   
    目录下的文章页面。
   
    百科搜索:
   
      在20多M的数据里进行全文搜索,只能放在服务器上了;如何中文分词、生成索引这些东西在这里不讲,原理就是用户输入关键字,会通过服务器返回一个html5页面;
   
    这时候用户可以查看详细页面,直接调用手机里的静态页面展现。
   
   
   
   
    最后说说jquery mobile的坑吧:
   
   
   
   
      说是坑也不过分,Android4以下的手机使用,感觉速度慢,Android4以上的手机速度一般,iphone手机用起来还可以接受,体验还行;
   
    对于 data-ajax="false"    这种使用呢可以解决闪屏的问题,但是无法记录用户上次打开的页面状态,我是被闪屏搞得太无语就使用了就把ajax给禁止了,有人会问啥叫闪屏?
   
    就是你点一个按钮或者链接,它闪页面1~2次,才开始切换。
   
   
   
   
   
    [javascript] view
     plaincopyprint?
   
   
   
   
   
   
    <a  data-ajax="false" href="./baike_type_4__category_4.html" data-cache="true" data-role="button"  data-theme="b">孕前</a>  
   
    使用jquery moblie先把html页面再浏览器下调试没错误了,再嵌入webview里,以免被折腾死,webview下调试不是很方便。    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之WebApp频道!

本文由 @凌雪 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved