자바스크립트는 V8Context에서만 호출할 수 있다. IRenderProcessMessageHandler의 OnContextCreated와 OnContextReleased 가 자바스크립트가 호출될 수 있는 환경의 범위를 제공한다. 각 프레임별로 호출되며 frame.IsMain으로 메인프레임여부를 판가름할 수 있다.
OnFrameLoadStart에서 DOM에 접근할 수 있으며 로딩이 완료되기 던에 DOM의 스크립트를 실행할 수 있다.
browser.RenderProcessMessageHandler = new RenderProcessMessageHandler();
public class RenderProcessMessageHandler : IRenderProcessMessageHandler {
// Wait for the underlying JavaScript Context to be created. This is only called for the main frame. // If the page has no JavaScript, no context will be created. void IRenderProcessMessageHandler.OnContextCreated(IWebBrowser browserControl, IBrowser browser, IFrame frame) { const string script = "document.addEventListener('DOMContentLoaded', function(){ alert('DomLoaded'); });";
frame.ExecuteJavaScriptAsync(script); } }
//Wait for the page to finish loading (all resources will have been loaded, rendering is likely still happening) browser.LoadingStateChanged += (sender, args) => { //Wait for the Page to finish loading if (args.IsLoading == false) { browser.ExecuteJavaScriptAsync("alert('All Resources Have Loaded');"); } }
//Wait for the MainFrame to finish loading browser.FrameLoadEnd += (sender, args) => { //Wait for the MainFrame to finish loading if(args.Frame.IsMain) { args.Frame.ExecuteJavaScriptAsync("alert('MainFrame finished loading');"); } };
* 스크립트는 프레임레벨에서 수행되고 모든 페이지는 한개 이상의 프레임으로 구성된다. * IWebBrowser.ExecuteScriptAsync 확장메서드는 하위호환성을 위해 남겨 있으며 main frame에서 js를 수행하는 숏컷처럼 사용가능하다. * frame이 자바스크립트를 포함하지 않으면 V8Context가 생성되지 않는다. * frame이 로드된 후 context가 없는 경우 IFrame.ExecuteJavaScriptAsync를 호출하여 V8Context을 생성할 수 있다. * OnFrameLoadStart가 호출될때 DOM 로딩이 완료되지 않는다. * IRenderProcessMessageHandler.OnContextCreated/OnContextReleased는 메인프레임에서만 호출된다.
결과를 리턴하는 자바스크립트 메서드의 호출은 ?
//An extension method that evaluates JavaScript against the main frame. Task response = await browser.EvaluateScriptAsync(script); //Evaluate javascript directly against a frame Task response = await frame.EvaluateScriptAsync(script);
자바스크립트는 비동기로 수행되기 때문에 에러메세지, 결과, 성공플래그등을 포함하는 Task를 반환한다. 자바스크립트가 수행될때 기본적으로 알아야 할 사항은 다음과 같다.
* 언제 호출하는게 가능한지에 대해 알아야 하며 위에서 설명하였다. * 프레임레벨에서 스크립트가 수행되고 모든 페이지는 하나이상의 프레임으로 구성된다. * 스크립트는 렌더프로세스내에서 수행되고 성능상의 이유로 IPC를 통해 전달되고 데이터만 반환한다. * 프리미티브 타입인 int, double, date, bool과 string이 제공된다. * 결과로 객체가 제공되고 IDictionary<string, object>형태로 접근을 더 용이하게하기 위해 dynamic 키워드가 제공된다. * 프리미티브타입이나 앞서 얘기한 객체가 IList
CefSharp.BindObjectAsync가 호출되면 JavascriptObjectRepository가 주어진 이름으로 인스턴스가 등록되어 있는지 확인한다. 만일 등록이 안되어 있다면 ResolveObject이벤트가 발생한다. 파라메터 없이 CefSharp.BindObjectAsync가 호출되면 등록된 경우 바운드가 되고 등록이 안되었으면 ObjectName을 All로 설정하여 ResolveObject가 모두 호출된다.
@Nullable @Override public PendingIntent createCurrentContentIntent(Player player) { int window = player.getCurrentWindowIndex(); return createPendingIntent(window); } }
플레이어에 연결은 다음과 같이 한다.
player = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector); playerNotificationManager.setPlayer(player);
플레이어가 해제되기 전에 먼저 연결을 끊어야 한다.
playerNotificationManager.setPlayer(null); player.release(); player = null;
커스텀하기
앱의 테마에 맞도록 알림을 커스텀하는 다양한 방법이 존재한다. 재생컨트롤의 동작여부를 설정하고 알림속성을 설정할 수 있도록 매니져가 기능을 제공한다. 이 속성들은 기본값을 가지고 있고 쉽게 바꿀수 있다.
재생컨트롤 액션들
기본 컨트롤액션을 제공한다. 재생/일시정지, FF/REW, Next/Previous, Stop등이 있으며 생략도 가능하다
// omit skip previous and next actions playerNotificationManager.setUseNavigationActions(false); // omit fast forward action by setting the increment to zero playerNotificationManager.setFastForwardIncrementMs(0); // omit rewind action by setting the increment to zero playerNotificationManager.setRewindIncrementMs(0); // omit the stop action playerNotificationManager.setStopAction(null);
커스텀액션도 CustionActionReceiver를 확장하여 구현하여 PlayerNotificationManager 생성자의 5번째 파라메터로 넣어서 구현 가능하다.
알림 속성
알림매니저는 UI와 알림의 동작의 setter를 제공한다. 이는 NotificationCompat.Builder의 속성에 상응한다.