ionic开发跨平台App常见问题 (转载)


本文转自http://www.ayqy.net/blog/ionic%E5%BC%80%E5%8F%91%E8%B7%A8%E5%B9%B3%E5%8F%B0app%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/?utm_source=tuicool&utm_medium=referral


写在前面

ionic是一个用来快速开发跨平台应用的框架,亮点不少:

  • 学习成本低

    对前端开发者来说,学习成本不是很高,如果有接触过angular,就几乎没有什么学习成本了

  • 简单易用

    强大的CLI,start->platform->serve->build->emulate->run,全套服务命令行完成,不用写配置文件,不用F5

  • 组件多而强大

    提供了很多强大的现成组件,很容易实现流行的交互效果,比如下拉刷新(ion-refresher)、上拉加载/瀑布流(ion-infinite-scroll)、tabs(ion-tabs)、侧边栏菜单(ion-side-menu)等等,只需要写一点点代码,就能实现这些流行效果,比native开发速度快太多了

  • 支持cordova插件

    打开了这扇门,意味着我们可以使用大量的原生功能,比如调用相机拍照、响应返回按钮、打电话发短信发邮件……都只要几行代码就能搞定

  • 更新速度快

    2015/11/1是v1.1.0,现在(2016/1/9)已经是v1.2.4了,快速更新意味着有人维护,bug能被迅速修复

    当然,也有缺陷,否则就没有这篇笔记了,如下:

  • 新版本不完全向后兼容

    不兼容没关系,给个详细文档说明下也行啊,没有

  • bug难以定位

    angular+cordova+ionic+javascript,发现问题后,很难确定是哪块的问题

  • 性能优化难

    动画卡顿,低端机体验更差,而优化措施一般都是建议少用动画少用阴影少用渐变……但是,不用实在太丑,而且与native应用体验差太多

  • 其它

    奇奇怪怪的问题找不到答案,大半夜的翻stackoverflow……

一.jsonp跨域,php服务怎么写

P.S.这是angular的问题,当时没整理笔记,后来就忘记了遇到过这么个问题

angular的$http可以发送jsonp请求,用法类似于jQuery,如下:
// 请求数据
$http.jsonp(sUrl).success(function(res){
    // ...
}).error(function(err){
    // ...
});

sUrl有特殊要求,必须带上callback参数,而且参数值只能是JSON_CALLBACK,angular文档:

Relative or absolute URL specifying the destination of the request. The name of the callback should be the string JSON_CALLBACK.

例如:

var sUrl = http://www.ayqy.net/app/rsshelper/index.php?callback=JSON_CALLBACK
而问题是:php服务怎么写?直接返回用JSON_CALLBACK()包裹的json数据?

不对,因为真正请求的url中callback !== JSON_CALLBACK,被angular偷偷(文档没有说明)替换掉了,所以后台需要这样写:
<?php
if (strpos($_SERVER["REQUEST_URI"], 'callback')) {
    $res = json_encode($res);
    // echo $_SERVER["REQUEST_URI"];
    // /angular/test/http/main.php?callback=angular.callbacks._0
    // $res = 'JSON_CALLBACK('.$res.')';
    // 错的
    $res = $_GET['callback'].'('.$res.')';
}
?>

当然,这是get的情况,比较简单,如果是post,还需要通过别的方式取callback,完整例子如下:

<?php
// get
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
    $res = '{';

    // arg
    if (isset($_GET['arg'])) {
        $res .= '"arg": "'.$_GET['arg'].'", ';
    }
    // method
    if (strpos($_SERVER["REQUEST_URI"], 'callback')) {
        // echo $_SERVER["REQUEST_URI"];
        // /angular/test/http/main.php?callback=angular.callbacks._0
        $res .= '"arg": "'.$_GET['arg'].'", ';
        $res .= '"method": "jsonp"}';
        // $res = 'JSON_CALLBACK('.$res.')';
        // 错的
        $res = $_GET['callback'].'('.$res.')';
    }
    else {
        $res .= '"method": "get"}';
    }

    echo $res;
}
// post
else if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 直接拿拿不到,因为传过来的是json串
    // echo $_POST['arg'];
    $jsonArg = file_get_contents('php://input');
    if (isset($jsonArg)) {
        echo substr($jsonArg, 0, strlen($jsonArg) - 1).', "method": "post"}';
    }
    else {
        echo '{"method": "post"}';
    }
}
?>

二.ion-content的阻尼回弹效果没了

   ionic v1.2取消了ion-content默认的阻尼回弹效果,明明一模一样的代码,就是没有回弹效果,后来发现是版本更新的锅,翻了很久后,在官方博客的评论里找到了答案:

Great news, thank you! It seems that the “has-bouncing=’true’” does
not work with the native scroll, is it correct? I managed though to
have it again by going to back go js scroll (overflow-scroll=”false”)

I only checked in the browser so if any one can confirm that with
native scrolling removes bouncing that would be great.

I need this feature for a custom ‘pull refresh’ method I had.

也就是说,v1.2之后想要有阻尼回弹效果,需要这么做:
<ion-content overflow-scroll="false" has-bouncing="true"></ion-content>

三.多个view之间的数据共享

也就是多个controller之间的数据共享(一般不同view对应不同controller)问题,当然,最简单的方法是用全局变量(`$rootScope`),但这样不好,更合理的方式是自己写个`service`或者`factory`,提供数据存取接口,在需要的地方依赖注入即可,比如:
.service('DataServ', ['$http', 'UIServ', function($http, UIServ) {
    // ...
    // 字典
    var oDir = {
        // key: value
    };

    function save(val) {
        var sKey = Date.now() + '';
        oDir[sKey] = val;
        return sKey;
    }

    function get(sKey) {
        return oDir[sKey];
    }

    return {
        // ...
        save: save,
        get: get
    };
}]);
然后通过url传递sKey即可实现数据共享,很干净

四.通知视图更新

在模板中写好了数据展示,但如果打开页面后数据还没到,模板解析完了,由于没有数据显示空白页,过了一会儿数据到了,发现视图没有更新,仍然是一片空白,比如: 
<!-- html -->
<p ng-cloak>{{data}}</p>

// js
app.controller('MainCtrl', ['$scope', 'DataServ', function($scope, DataServ) {
    // ...
    setTimeout(function() {
        // ...
        $scope.data = 'data';
    })
}]);
因为给data赋值的操作跑到了controller作用域外,此时需要手动通知视图更新,如下:
// ...
$scope.data = 'data';
$scope.$apply();
当然,一般不需要手动通知,即便是异步返回的数据,因为这里只与作用域有关,总之,如果发现视图需要手动更新,添上$apply就好了

五.php原生xml扩展如何获取里的内容

rss格式中会有<content: encoded>标签,直接取content取不到,需要特殊的方式:
$content = (string)$item->children("content", true);
// $encodedContent = $content->encoded;
// $content->encoded返回转义过的html,比如把&amp;转成&,一般用于<pre>直接展示
当然,前提是使用原生xml扩展($xml = simplexml_load_file($url);)解析xml才会遇到这个问题,更多用法请查看php – How to parse CDATA HTML-content of XML using SimpleXML? – Stack Overflow

六.在浏览器中打开外部页面

需要使用一个cordova插件,cd进项目文件夹,然后:
ionic plugin add cordova-plugin-inappbrowser
安装完成后就可以调用了,不用修改配置文件,不用引入其他js,如下:
// openInBrowser
window.open(‘http://example.com’, ‘_system’);   Loads in the system browser
window.open(‘http://example.com’, ‘_blank’);    Loads in the InAppBrowser
window.open(‘http://example.com’, ‘_blank’, ‘location=no’); Loads in the InAppBrowser with no location bar
window.open(‘http://example.com’, ‘_self’); Loads in the Cordova web view
// test
window.open(url, '_system'); // 系统默认浏览器
// window.open(url, '_blank');  // 很丑的安卓内置浏览器
// window.open(url, '_self');  // 同上
一般都用_system,另外两个实在太丑,更多内容请查看[Cordova InAppBrowser Plugin Example using ionic framework](http://sourcefreeze.com/cordova-inappbrowser-plugin-example-using-ionic-framework/)

七.splash screen黑屏白屏

P.S.黑屏白屏其实是同一个问题,但这个问题相当难解决,笔者花了快1天才搞定

ionic默认集成了splashscreen插件,这个cordova插件效果不是很完美,默认配置只在首次打开app时显示splash screen,但实际效果是:

When the app starts the splash screen shows for a few seconds as expected, and then the screen goes black for @1 second and then white for @2 seconds and then the main app page appears.

Is there any way to prevent the black and white pages appearing? I
read somewhere that a black page appears when there is no splash page
but I do have a splash page and it appears fine.

在[stackoverflow](http://stackoverflow.com/questions/33444216/ionic-run-android-shows-black-and-white-screens-before-main-app-page)找到了这个问题描述,简直太贴切了,但是单靠问题下面的回答无法解决白屏问题,还需要改配置文件

最初发现的现象是黑屏(把上面英文描述里的white换成黑),后来找到了原因:主视图容器`ion-nav-view`是空的,而它的背景色是#000,所以修复方法是给里面塞个ion-view:
<!-- 内容 -->
<ion-nav-view>
    <!-- 防止启动时黑屏 -->
    <ion-view></ion-view>
</ion-nav-view>
或者添css,把`ion-nav-view`的背景色改成白色。但问题还没解决,黑屏问题变成白屏问题了,解决方案比较麻烦

1.把splashscreen插件降级到v2.0.0
v2.0.0之后的版本有bug,目前(2016/1/9)自带的版本是v3.0.0。先cd到项目文件夹,然后命令行:

// 删掉现有版本
cordova plugin rm cordova-plugin-inappbrowser
// 安装v2.0.0
cordova plugin add cordova-plugin-inappbrowser

2.改配置文件MyApp/config.xml

<preference name="SplashScreen" value="screen"/>
<preference name="AutoHideSplashScreen" value="false"/>
<preference name="auto-hide-splash-screen" value="false"/>
<preference name="ShowSplashScreenSpinner" value="false"/>
<preference name="SplashMaintainAspectRatio" value="true" />
<preference name="SplashShowOnlyFirstTime" value="false"/>
<preference name="SplashScreenDelay" value="10000"/>
取消自动隐藏(改为代码控制隐藏),把持续时间改为较大的值(10秒),设置每次打开应用都显示splash screen

P.S.默认只有`SplashScreen`和`SplashScreenDelay`,需要把其它的(`SplashMaintainAspectRatio`可选)都添上

3.改app.js

手动隐藏splash screen,在run里面添上
.run(['$rootScope', function($rootScope) {
        // init
        // $rootScope.isLoading = false;

        // hide splash immediately
        if(navigator && navigator.splashscreen) {
            navigator.splashscreen.hide();
        }
    });
}])
这样就好了,不要延时调用hide,否则仍然会出现白屏(有些解决方案要求$timeout 50毫秒hide,仍然会出现白屏,不要这样做)

最怨念的问题结束了,看似简单的功能,想要有完美的原生体验却很难,奇奇怪怪的问题很难解决,目前可行的解决方案可能过段时间就不行了,可以查看White page showing after splash screen before app load感受一下

八.安卓版本签名发布

各种签名方法都过时了,目前(2016/1/9)可以用的签名方法如下:

1.在MyApp\platforms\android创建keystore

具体步骤请查看:[Ionic toturial for building a release.apk](https://forum.ionicframework.com/t/ionic-toturial-for-building-a-release-apk/15758)

2.创建release-signing.properties文件

具体步骤请查看:[How to automatically sign your Android apk using Ionic framework and Crosswalk](https://baxeico.wordpress.com/2015/05/20/how-to-automatically-sign-your-android-apk-using-ionic-framework-and-crosswalk/)

3.build
cd到项目文件夹,然后命令行`ionic build --release android`,成功后会生成2个东西,在MyApp\platforms\android\build\outputs\apk下,分别是android-armv7-release.apk和android-x86-release.apk,一般平板和PC用x86,手机用arm7,如果要上传google play的话,2个都要传,下载时有自动识别

至于crosswalk,提供了chrome内核,能让低端机支持高端东西,但会让apk变大很多(3.5M->23M),添上crosswalk后,感觉。。。嗯,变卡了,但为了支持低端机用户,一般都会添上crosswork

九.总结

怎么说呢,快速开发很棒,后遗症很伤。

笔者从1月3号开始搞,1月8号中午release v1.0.0,靓照如下:

这里写图片描述

rsshelper

这里写图片描述

rsshelper

看着还不错吧,非卖品,不赠送~

本文转自http://www.ayqy.net/blog/ionic%E5%BC%80%E5%8F%91%E8%B7%A8%E5%B9%B3%E5%8F%B0app%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98/?utm_source=tuicool&utm_medium=referral

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值