<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [Xamarin]我的Xamarin填坑之旅(二)

        上一篇交代了我Xamarin填坑的背景,大概聊了聊第一步環境配置,第二步創建項目和開發框架選擇。如果有一個可用的梯子,這部分基本不會出錯。


       

        接下來就具體聊一聊寫代碼的過程中遇到的一些事兒。

        第三步是碼代碼:

        ①Http相關:

        我做的項目是一個校園助手,目前提供的功能絕大多數是查詢功能。或者說,就是簡單的爬蟲,從校園服務器上爬取相關網頁。因此,結合校園網站以及我的自身需求,我寫了一個簡單的用于發送Http請求的服務類HttpService,封裝了一些Request方法:

      public async Task<string> SendRequst(string uri, HttpMethod method, IDictionary<string, string> dic = null, string referUri = "", CancellationToken cancellation = new CancellationToken())
              {
                  HttpResponseMessage response = null;
                  Encoding encoding = Encoding.UTF8;
                  try
                  {
                      if (!string.IsNullOrEmpty(referUri))
                      {
                          _client.DefaultRequestHeaders.Referrer = new Uri(referUri);
                      }
      
                      if (method == HttpMethod.Get)
                      {
                          response = await _client.GetAsync(uri, cancellation);
                      }
                      else
                      {
                          FormUrlEncodedContent content = new FormUrlEncodedContent(dic);
      
                          response = await _client.PostAsync(uri, content, cancellation);
                      }
                      var mediaTypeHeaderValue = response.Content.Headers.ContentType;
                      if (mediaTypeHeaderValue != null && mediaTypeHeaderValue.CharSet != null)
                      {
                          if (mediaTypeHeaderValue.CharSet.Contains("gb2312"))
                          {
                              encoding = Encoding.GetEncoding("gb2312");
                          }
                      }
                      using (var stream = await response.Content.ReadAsStreamAsync())
                      {
                          byte[] buffer = new byte[stream.Length];
                          await stream.ReadAsync(buffer, 0, buffer.Length);
                          var str = encoding.GetString(buffer,0,buffer.Length);
      
                          return str;
                      }
                  }
                  catch
                  {
                      throw;
                  }
                  finally
                  {
                      response?.Dispose();
                  }
              }
      View Code

      這段代碼本身沒有問題,但是在Xamarin中有個坑。由于需要用到gb2312編碼方式,但是我在調試安卓項目的時候,卻遇到類似“not support 936 code page”錯誤,解決的辦法就是在安卓項目屬性中添加CJK編碼方式支持。

        這兒有一個最佳實踐,分享自周岳老師

      一般所有的Http請求通過HttpClient發起,每一個HttpClient的對象都幫我們維護了Http請求的一些基本信息,包括本地緩存,Cookie等。那默認的,如果Xamarin中直接使用HttpClient,它的實現完全是.net的實現方式。在這兒,可以通過ModernHttpClient來完成一些優化。

      在創建HttpClient的時候,可以傳入一個ModernHttpClient.NativeMessageHandler實例,作為默認的Handler。這樣在Android平臺會使用OKHttp來執行一些Http請求,細節可以看作者的Github

      HttpClient client=new HttpClient(new ModernHttpClient.NativeMessageHandler() );

       

        Nuget:ModernHttpClient

        GitHub:ModernHttpClient

        在Http請求這塊兒,除了上面這個最佳實踐,其他部分可以100%重用我UWP項目中的代碼。基本無需任何修改。

       

        ②HTML Parse:

        因為校內網站很少有直接提供REST API服務,所以必須自己從各個頁面解析數據。對于Dom的分析,我選擇使用AngleSharp這個工具。這個工具現在已經可以支持Xamarin了。

        值得高興的是,個別站點使用了JSON傳送數據,針對JSON的解析,目前.Net平臺最權威的就是Newtonsoft.Json這個庫了,配合Newtonsoft.Json以及.Net的dynamic動態類型,很容易能完成Json的解析。Xamarin完全支持!所以這部分的代碼也是100%重用。

           官網:AngleSharp

       

        ③XXXService:

        在上面介紹的Http相關請求中,為了使用方便,我封裝了一個基本的HttpBaseService類,主要就是這層各種XXXService獲取數據。校園助手目前是以查詢為主,包括查詢成績,課表等教務相關的信息,查詢一卡通余額,消費,解/掛失等簡單的個人信息。于是針對不同的功能大類別,我封裝了諸如EduService,InfoService等類,在類中實現了一些方法,用來完成獲取數據,解析數據的功能。對這些方法的調用,都是由ViewModel層來完成,所以這部分代碼和UWP項目中的也是所差不多。

       

        ④ViewModel:

        根據MVVM的特點,原則上是一個View對應一個ViewModel。ViewModel層和我UWP項目中的一樣,變動不多。但是,在UWP項目中,我使用的是MVVMLight這個框架,而在Xamarin中選擇了微軟自家的Prism,所以在消息通知,頁面導航等方面會有一些不同。下面列舉一些使用Prism MVVM時的一些內容。

      •   關于頁面導航:Prism在頁面導航方面,提供了一個接口Prism.Navigation.INavigationService,采用構造函數注入的方式。
      •   關于加載數據的問題:每當創建一個ViewModel,我們希望去獲取一些數據,可能是存儲在本地的,也可能要從網絡上獲取的。但是考慮到性能問題,這部分數據不能放在構造函數里面。

            1.比較好的辦法就是當導航到ViewModel對應的View的時候,再去加載數據,Prism框架提供了這樣一個接口來實現相關的功能

      public interface INavigationAware
      {
          void OnNavigatedFrom(NavigationParameters parameters);//從當前頁面離開時
          void OnNavigatedTo(NavigationParameters parameters);//導航到當前頁面時
      }

            可以通過實現該接口,然后在OnNavigationTo方法中去加載一些數據。當然這個接口的作用不限于此,主要作用還是處理頁面導航時傳遞的參數。

            2.還有一個我在UWP中常用的辦法,就是自定義一個OnLoad方法,然后綁定到View的Loaded事件上面。但這兒有一個很尷尬的問題,Xamarin的Page中并沒有一個Loaded事件,相對變通的是它有一個Appearing事件,可以當作Loaded來用。具體的綁定方法如下:

      public partial class XXXPage : ContentPage
          {
              public XXXPage ()
              {
                  
                  InitializeComponent();
                  this.Appearing += XXXPage _Appearing;
              }
      
              private void XXXPage _Appearing(object sender, System.EventArgs e)
              {
                  LoadedCommand?.Execute(null);
              }
      
              public static readonly BindableProperty LoadedCommandProperty = BindableProperty.Create("LoadedCommand", typeof(ICommand), typeof(CampusCardPage), defaultBindingMode: BindingMode.OneWay);//用于綁定的依賴屬性
              public ICommand LoadedCommand
              {
                  get { return (ICommand)GetValue(LoadedCommandProperty); }
                  set { SetValue(LoadedCommandProperty, value); }
              }
          }
      View Code

            上述代碼大致在Page中實現一個自定義的LoadedCommand,然后在頁面觸發Apearing事件的時候,調用該命令的Excute方法,命令則通過數據綁定進行賦值,與ViewModel中的LoadedCommand相相綁定,這也是為什么把LoadedCommand定義為依賴屬性的原因。

          通過上面提到的1,2兩點,就可以在導航到頁面以后加載一些數據了,如果配合.net的async/await異步編程模型,就能更加流暢的實現數據加載了。

       

        ④Views:

        針對View的編寫是這次踏坑Xamarin最耗時的部分。雖然Xamarin.Forms可以用Xaml來編寫頁面,但是和UWP的XAML比起來,功能上差不多,體驗上卻很不好,尤其是自動補全和智能感知等方面。所以寫代碼會寫的很累。這些其實還好解決,畢竟熟悉一段時間后就基本沒有障礙了。唯一欠缺的就是針對XAML代碼的Previewer了,雖然今年的Connect()2016大會上,Xamarin Studio里面已經集成了初步的Previewer,但目前離正式發布還有一段距離,尤其是在VS里面。針對這點,給出一個稍微便捷的應對辦法。使用工具Gorilla-Player,在真機上預覽。具體使用可以看他的WIKI,下面展示一個使用該工具的截圖

      當然目前這個工具問題還挺多,比如不支持靜態資源的引用等。在吐槽的同時,還是需要靜靜的等待官方的previewer正式發布。

        針對View也有一個最佳實踐:

      因為現在XAML編輯器還不能很好的提供智能感知和自動補全等功能,所以在自己寫一些屬性的時候,很容易出現拼寫錯誤的問題。往往這種錯誤在編譯的時候,并不會被編譯器檢查到,于是錯誤就會發生在運行時,往往耗時耗力。Xamarin為我們提供了一個特性,叫做XamlCompilationAttribute,用來提供編譯程序集時候的XAML拼寫檢查等任務。他可以應用到整個程序集,也可以之應用在單個的View上。只需要指定其參數為XamlCompilationOptions.Compile即可。

      [assembly: XamlCompilation(XamlCompilationOptions.Compile)]//用于整個程序集
      [XamlCompilation(XamlCompilationOptions.Compile)]//只用于單個Page/View

      當然XamlCompilation怎么可能會只提供這么一點特性呢?它可以提升整個XAML的性能,通過預編譯為IL代碼的方式,減少加載XAML的時間。具體看官方文檔:

      XamlCompilation(https://developer.xamarin.com/guides/xamarin-forms/xaml/xamlc/)

        

        ⑤數據存儲:

        一個完整的App,必須有本地存儲,無論是緩存一些文件,還是存儲一些必要配置信息。Xamarin跨平臺提供了統一的數據存儲方式,但是在不同的平臺上,具體實現是不同的。數據存儲方面,我選擇了SQLite這個輕量級的數據庫,這也是移動開發本地存儲最適合的數據庫之一了。好在現在也有比較成熟的ORM工具來支持SQLite了。
        Xamarin官方實例(https://developer.xamarin.com/guides/xamarin-forms/working-with/databases/)
        nuget:sqlite-net-pcl(https://www.nuget.org/packages/sqlite-net-pcl)

       


        補幾張圖結束本篇

               

        在碼代碼的過程中,還遇到過一些其他的坑,以后慢慢更,因為這是連載系列......

       

      posted @ 2016-12-09 14:24  DemoApp  閱讀(4404)  評論(15)    收藏  舉報
      主站蜘蛛池模板: 亚洲中文久久久精品无码| 波多野结衣久久一区二区| 国产一区二区三中文字幕| 男女啪啪免费观看网站| 亚洲人成网站在线播放2019| 精品一区二区久久久久久久网站| 丰满少妇高潮无套内谢| 卓资县| 国产成人一区二区三区视频免费| 无码一区二区三区中文字幕 | jk白丝喷浆| 又大又紧又粉嫩18p少妇| 亚洲av成人在线一区| 国产精品自在自线免费观看| 影音先锋女人AA鲁色资源| 久久亚洲精品中文字幕无| 亚洲午夜香蕉久久精品| 亚洲国产成人久久综合一区77 | 免费午夜无码片在线观看影院| 亚洲中文字幕综合小综合| 狠狠色狠狠色综合日日不卡| 欧美日本一区二区视频在线观看| 一本一道av无码中文字幕﹣百度| 日本一区二区三区黄色网| 欧洲免费一区二区三区视频| 国产麻豆剧果冻传媒一区| 欧洲国产成人久久精品综合| 亚洲成a人无码av波多野| 婷婷四虎东京热无码群交双飞视频 | 欧美老少配性行为| 国产最新精品系列第三页| 成熟了的熟妇毛茸茸| 亚洲av本道一区二区| 中文字幕有码日韩精品| 成人一区二区三区在线午夜| 亚洲国产精品无码一区二区三区| 人妻系列中文字幕精品| 国产av国片精品一区二区| 亚洲欧洲日产国产av无码| 久久成人国产精品免费软件| 日本极品少妇videossexhd|