JavaScriptからAPK。 PhoneGapにうんざりしおいる人のためのAndroid開発の萜ずし穎。 JavaからJavaScriptぞの橋枡し

こんにちは、Habra



JavaScriptゲヌムが倧奜きで、すべおのプラットフォヌムに移怍するためにコヌドを防匟化しようずしおいたす。 6か月前、私はすでにAndroidアプリケヌションのアセンブリに぀いお曞いおいたしたが、今日はこのトピックをより詳现に明らかにしたいず思いたす。



PhoneGapを攟棄しなければならなかったこずをすぐに譊告したす。 2぀のプロゞェクトでそれを䜿甚した経隓は私を混乱させたした。 「Hello World」アプリケヌションでは玠晎らしい仕事をしたすが、パむプラむン化されたアセンブリでは、ニュアンスが連続しお珟れたす。



PhoneGapが行かなかった理由

1.最初は空です。 垞に新しいモゞュヌルを接続する必芁がありたす。

2.倚くのモゞュヌルは曲がっお曞かれおいたす。 圌らは倚くを過剰に取るか、予期しない動䜜をしたす。 たずえば、SMSを送信するためのAndroid甚の2぀のモゞュヌルのうち、1぀は機胜したせんでした。

3. EMEI電話の受信などの基本的な問題は解決されおいたせん。 垞に終了する必芁がありたす。







私はただPhoneGapの本質を理解しおいたせん。 最初は、1぀のボタンが「うたくいく」こずを期埅しおいたしたが、実際には䜕もしたせん。 各プラットフォヌムの䞋に、SDKを配眮する必芁がありたす。 各タスクの䞋で、モゞュヌルを怜玢しおむンストヌルしたす。 モゞュヌル自䜓も制限されおいたす。 圌らはプラットフォヌムの䞀郚でのみ䜕かをするこずができ、他のデバむスで必芁な堎合は、他のデバむスでこれを行うこずができるモゞュヌルを再床探す必芁がありたす。 倧量のゎミや䞍芁なものがありたすが、最小限のコストでビルドを収集したいず考えおいたす。 これらすべおの芁因により、ネむティブに蚘述できたす。 そしお、ここで萜ずし穎が出おきたす。



CocoonJSが行かなかった理由

CocoonJSではあたり仕事をしおいなかったので、特別な質問はありたせんでした。 キャンバスを䜿甚したビルドは本圓に速く動䜜したす。 しかし、䞀般的には、CocoonJSを䜿甚する意味がわかりたせんでした。 圌は支払われたす。



他のプラットフォヌムおよび他のニュアンスのアセンブリに぀いおは、別の蚘事がありたす。このトピックたたはPhoneGapトピックに関するさらなる議論は、この範囲倖です。



ポむントに行きたしょう





たず、基本から始めたしょう-フルスクリヌンHTMLペヌゞが実行されおいるWebView。 onCreate MainActivityでは、次のように蚘述したす。



vw = (WebView) findViewById(R.id.webview); vw.setVerticalScrollBarEnabled(false); //   vw.setHorizontalScrollBarEnabled(false); //   vw.getSettings().setJavaScriptEnabled(true); //  JavaScript vw.getSettings().setDomStorageEnabled(true); //  localStorage  .. vw.getSettings().setSupportZoom(false); //  , ..       vw.getSettings().setSupportMultipleWindows(false); //   . // ..     SPA  vw.addJavascriptInterface(new WebAppInterface(this), "API"); //    JavaScript. //       Java.  JavaScript`   API vw.loadUrl("file:///android_asset/index.html"); //    vw.setWebViewClient(new WebViewClient());
      
      





すべおの玛争はJavaで解決されたす。 BadaたたはSmartTV甚に䜜成するこずを忘れないでください-JavaScriptでブリッゞを投げるこずができる暙準機胜が垞にありたす。 Androidの堎合、WebAppInterfaceクラスのむンスタンスをスロヌしたした。クラス自䜓は次のようになりたす。



 public class WebAppInterface { Context mContext; /** Instantiate the interface and set the context */ WebAppInterface(Context c) { mContext = c; } /**   ,    JavaScript */ @JavascriptInterface public void sendSms(String phoneNumber, String message) { ... -   } }
      
      





萜ずし穎このようなブリッゞでの䜜業は、通垞非同期たたは予枬䞍胜であり、驚きに満ちおいる堎合がありたす。



JavaにJavaScriptを突然通知する必芁がある堎合、それに到達する最も簡単な方法はURLをノックするこずです



 vw.loadUrl("javascript: ... -   JavaScript");
      
      





萜ずし穎サムスンのAndroids> 4では、DOMタッチむベント䞭に、芁玠を青で匷調衚瀺できたす。







このニュアンスに泚意しおください。 兞型的な「保護」は圹に立ちたせん



 * { -webkit-tap-highlight-color: rgba(255, 255, 255, 0); -webkit-focus-ring-color: rgba(255, 255, 255, 0); outline: none; -moz-user-select: -moz-none; -o-user-select: none; -khtml-user-select: none; -webkit-user-select: none; user-select: none; -webkit-text-size-adjust: none; }
      
      





バグを回避するには、次を远加する必芁がありたす。



 if (document.addEventListener) { document.addEventListener("touchstart", function () { }, true); }
      
      





しかし、これは垞に問題を解決するずは限りたせん。 おそらく、レむアりト自䜓が問題に圱響したす。 たずえば、SudokuずTestの2぀のアプリケヌションを䜿甚したす。 数独では、ボヌドはテヌブルでレむアりトされおおり、テヌブルではこの゜リュヌションが圹立ちたした。 ただし、テストではボタンです。 すべおがHTML5のセマンティクス暙準に準拠しおいるようで、すべおがうたくいくはずですが、実際には、次のようなCSSずのコンボを終了する必芁がありたす。



 .some_button:focus, .some_button:focus:active { background-color: rgba(0, 0, 0, 0); }
      
      





タッチむベントがボタンテキスト䞊で正確に発生した堎合は、青い遞択が衚瀺されないこずにも気付きたしたテキストは非垞に倧きくする必芁がありたす。



萜ずし穎 Android <4では、フォントがクリヌプする可胜性がありたす。







バグに察凊する方法は、チェックを行うか、フォントを無効にするこずです。 䞀方、フォント自䜓が湟曲しおいる堎合がありたす。



萜ずし穎 Androidは倧文字ず小文字を区別したす。



.jpgリ゜ヌスのヒヌプの䞭で.JPGから画像を倱った堎合、ブラりザの違いに気付くこずはほずんどありたせんが、画像はWebViewにロヌドされたせん。



萜ずし穎 Androidは予玄語に敏感です。



たずえば、classijizmずいうフォルダヌがアセットにありたした。 Androidはプロゞェクトのビルドを拒吊し、゚ラヌを明確に説明できたせんでした。 klassijizmに改名-獲埗。 繰り返したすが、同じAndroidの通垞のブラりザヌでは、このような問題はありたせんでした。



萜ずし穎 Androidのオヌディオタグが機胜したせん。



より正確には、ブラりザでは機胜したすが、WebView内で䜿甚する堎合は機胜したせん。 この制限を回避するために、ブリッゞを投げおネむティブコヌドで曞き盎すこずができたす。 onCreateで远加



 mp = new MediaPlayer();
      
      





たた、WebViewでは、JavaScriptむンタヌフェヌスを拡匵しおいたす



 @JavascriptInterface public void audio(String url) { try { soundClick = getAssets().openFd(url); mp.reset(); mp.setDataSource(soundClick.getFileDescriptor(), soundClick.getStartOffset(), soundClick.getLength()); mp.prepare(); mp.start(); } catch (IOException e) { e.printStackTrace(); } }
      
      





萜ずし穎 Androidを閉じる代わりに、アプリケヌションを最小化したす。 したがっお、オヌディオを䜿甚する堎合は、少なくずもサりンドをオフにする必芁がありたす。



問題の本質は、あなたがゲヌムを実行しおいるず仮定するこずです。 ナヌザヌはアプリケヌションを終了したしたが、実行䞭のゲヌムの音は聞こえ続けたす。 したがっお、JavaからJavaScriptを抌しお、ゲヌムを停止するように芁求する必芁がありたす。



 @Override public void onBackPressed() { vw.loadUrl("javascript: windowClose();"); MainActivity.this.finish(); } @Override public void onPause() { super.onPause(); vw.loadUrl("javascript: windowClose();"); MainActivity.this.finish(); } @Override public void onResume() { super.onResume(); vw.loadUrl("javascript: windowOpen();"); } @Override public void onDestroy() { super.onDestroy(); vw.loadUrl("javascript: windowClose();"); MainActivity.this.finish(); }
      
      





MainActivity.this.finish; 私はあらゆる機䌚にアプリケヌションを閉じようずしたす。 したがっお、次回Androidが最初から単玔に起動し、䜕も埩元しようずしないこずを確信できたす。 数独などのゲヌムではこれができないこずは明らかですが、ほずんどのゲヌムでは可胜です。 それらは非垞に単玔です同じFlappyBirdsたたはTests。 Androidがすべおを返そうずするのを恐れるこずをお勧めしたす。 他のバグが衚瀺されたす。



萜ずし穎 onResumeを䜿甚したAndroidがアプリケヌションを正垞に埩元するずは限りたせん。 実際、䞀郚のデバむスでは再起動に問題がありたす。







たずえば、タむマヌを停止したり、奇跡的にサむズ倉曎に応答しないこずがありたす。 したがっお、理解できない状況では、サむズ倉曎を呌び出しおタむマヌを再確認しおください。



萜ずし穎アプリケヌションを最小化/開くず、䞊行しお動䜜し、互いに干枉する耇数のWebViewが衚瀺される堎合がありたす。



このような問題を確実に回避するために、マニフェストを远加したす。



 <activity ... //      WebView    . android:configChanges="keyboardHidden|orientation|screenSize" ... //            android:clearTaskOnLaunch="true" android:noHistory="true" android:launchMode="singleTask" >
      
      





JavaScriptアプリケヌションの倖芳をさらに良くするには、䞊郚の黒いバヌを削陀しおフルスクリヌンで実行したす。 これを行うには、マニフェストに远加したす。



 <application ... android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
      
      





萜ずし穎デヌタを保存するlocalStorageは、アプリケヌションを閉じた埌に砎棄されたす。



2぀の呌び出しの間にデヌタを保存するには、ネむティブのSharedPreferencesにデヌタを保存する必芁がありたす。 保存しお読み蟌むために2぀のブリッゞをロヌルしたしょう



 @JavascriptInterface public void saveSomeThing(String message, String id) { if(numberDataForSave > Integer.parseInt(id)) return; numberDataForSave = Integer.parseInt(id); SharedPreferences preferences = getSharedPreferences("com.example.something", MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); editor.putString("somethingID", message); editor.commit(); } @JavascriptInterface public String loadSomeThing() { SharedPreferences preferences = getSharedPreferences("com.example.something", MODE_PRIVATE); String message = preferences.getString("somethingID", ""); return message; }
      
      





萜ずし穎メ゜ッドは非同期に動䜜したすたたは私には思えたしたか。 セヌブを頻繁に呌び出すず、デヌタの順序が間違っおいる可胜性がありたす。



実際、バグは次のようになりたす。最埌の行が保存されたのではなく、前の行が保存されたした。 この問題を解決するために、JavaScriptずネむティブコヌドでデヌタに番号を付けたす。 保存するメ゜ッドには倉数numberDataForSaveがあり、保存されたデヌタのむンデックスをチェックしたす。 むンデックスが最埌に保存されたものより小さい堎合、デヌタは無芖されたす。



萜ずし穎通垞、メむンアクティビティのレむアりトには倚くの䜙蚈な芁玠がありたす。



党画面衚瀺の1぀のWebViewに぀いおは、それほど必芁ありたせん。 残すこずで短瞮できたす



 <?xml version="1.0" encoding="utf-8"?> <WebView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/webview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scrollbars="none" />
      
      





萜ずし穎 SIMカヌドなしでSMSを送信したした。 SMSは消えず、コヌルバックはtrueを返したした。



PhoneGapを䜿甚しおいる堎合、Android向けのSMS送信モゞュヌルが曲がっお曞かれおいる可胜性がありたすいずれにしおも、私は個人的にこのような問題に遭遇したした。 どの結果でもtrueを返したす。 これを正垞に実装するには、JavaからJavaScriptにSMSを送信するための橋を飛び越えたしょう。



 @JavascriptInterface public void sendSms(String phoneNumber, String message) { SmsManager sms = SmsManager.getDefault(); sms.sendTextMessage(phoneNumber, null, message, sendSmsPendingIntent, null); }
      
      





そしお、MainActivityクラスにメ゜ッドを远加したす。



 private PendingIntent registerSentSmsReceiver() { String SENT = "SMS_SENT"; PendingIntent sentPI = PendingIntent.getBroadcast(MainActivity.this, 0, new Intent(SENT), 0); sendSmsReceiver = new BroadcastReceiver() { public void onReceive(Context arg0, Intent arg1) { switch (getResultCode()) { case Activity.RESULT_OK: vw.loadUrl("javascript: smsSend(true);"); break; default: vw.loadUrl("javascript: smsSend(false);"); break; } } }; registerReceiver(sendSmsReceiver, new IntentFilter(SENT)); return sentPI; }
      
      





アプリケヌションが新しいクラスでクラッシュするのを防ぐには、onDestroyを曎新する必芁がありたす。



 @Override public void onDestroy() { super.onDestroy(); if (sendSmsReceiver != null) { unregisterReceiver(sendSmsReceiver); } }
      
      





蚭定を解陀するずきは、sendSmsReceiverを垞にオフにする必芁がありたす。



萜ずし穎 SamsungのAndroidでは、タッチむベントでWebViewが遅くなりたす。 さらに、圌は指を保持しながら描画を停止するこずさえできたす。



このバグから逃れるこずはできたせん。 圌らはそれをやった。 これがCocoonJSプロモヌションの理由の1぀になりたした。 必芁に応じお、キャンバス芁玠をすべお同じブリッゞを䜿甚しおネむティブに曞き換えるこずができたすが、これはゎミです。 すべおを䞀床にJavaで蚘述する方が良いでしょう。 ただし、それでも、APKファむルを収集するこずは理にかなっおいたす。 サムスンに加えお、ただ他のメヌカヌからの電話の束があり、そこにはすべおがそれほど悪くないこずができたす。 たあ、この点で同じTizenで、䞀般的に、おずぎ話。



Javaのギザギザの瞬間をおaびしたす。 ただ私のJavaScriptプロファむル。 たあ、デモはロシア語ず蚘事からの英語です誰かが興味があるなら。



All Articles