Перейти к содержанию
Fire Monkey от А до Я

serser

Пользователи
  • Постов

    16
  • Зарегистрирован

  • Посещение

Посетители профиля

862 просмотра профиля

Достижения serser

  1. На самом деле нужно делать так: TJParcelable.Wrap((PendingIntent as ILocalObject).GetObjectID) и TJPendingIntent.Wrap((Parcelable as ILocalObject).GetObjectID) Но ожидаемого результата использования TAndroidHelper.Activity.createPendingResult не получилось. После TMessageManager.DefaultManager.SubscribeToMessage(TMessageResultNotification, HandleActivityMessage); HandleActivityMessage не получает результат из сервиса с помощью PendingIntent.send. Будь неладен тот день для ider-ы, когда я решил написать приложение с сервисом на дельфи, уже два месяца я не могу получить результат от сервиса:то 1. createPendingResult приложение не получает результат. 2. для resultReceiver не хватает возможности получить результат в активити - переопределить onReceiveResult Остаются способы PendingResult.getAction и PendingResylt.getBroadcast. Первый способ ( ) - уродский, уж извините, если закрыть приложение оно опять появится после ответа сервиса. Второй, только его и остается проверить. Но идеологически он кажется неверным - использовать рассылку сообщений всей системе для своего, между мальчиками, общения тоже неверно. Получается нельзя тут взрослое приложение-то сделать , только кошечек рисовать.
  2. Получается Segmentation fault PIntent на момент присваивания = nil И это явно не простое присваивание, потому что во время него 10 раз в логе пишется switching thread, потом появляется эксепшн. Передаю интент в сервис так: class procedure TssAndroidServiceHelper.StartService(const AServiceName: string; AIntent: JIntent); var PendingIntent: JPendingIntent; begin PendingIntent := TAndroidHelper.Activity.createPendingResult(1, AIntent, 0); AIntent.setClassName(TAndroidHelper.Context.getPackageName(), TAndroidHelper.StringToJString(AServiceName)); AIntent.putExtra(StringToJString('q'), JParcelable(PendingIntent)); TAndroidHelper.Activity.startService(AIntent); end; Получаю так: TDM = class(TAndroidService) function AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer; procedure AndroidServiceCreate(Sender: TObject); private FPIntent: JPendingIntent; FStr: string; FThread: TssThread; procedure StartThread; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; end; function TDM.AndroidServiceStartCommand(const Sender: TObject; const Intent: JIntent; Flags, StartId: Integer): Integer; var ResultIntent: JIntent; Parcelable: JParcelable; begin Parcelable := Intent.getParcelableExtra(StringToJString('q')); FPIntent := JPendingIntent(Parcelable); ResultIntent := TJIntent.Create; ResultIntent.putExtra(StringToJString('res'), StringToJString('content')); FPIntent.send(TAndroidHelper.Context, 7, ResultIntent); Result := TJService.JavaClass.START_STICKY; end; Есть еще идеи как вытащить отложенное намерение?
  3. Помогите достать JPendingIntent из JIntent. Пытаюсь из сервиса получить отложенный интент, созданный с помощью TAndroidHelper.Activity.createPendingResult. Делаю так: var Parcel: JParcelable; PIntent: JPendingIntent; begin Parcelable := Intent.getParcelableExtra(StringToJString('pendingintent')); PIntent := Parcelable ; ... end; Получается ошибка: E2010 Incompatible types: 'JPendingIntent' and 'JParcelable' Как приводить эти интерфейсы друг к другу?
  4. Ясно) Вот и разобрались немного в вопросе) Спасибо всем!
  5. Выходит, если мы рисуем на одной канве из двух потоков и у нас одновременно открыты в каждом Canvas.BeginScene, то после прорисовки по Canvas.EndScene на канве отобразиться суммарная картинка? Исходя из реализации TCanvasGpu: function TCanvasGpu.DoBeginScene(const AClipRects: PClipRects; AContextHandle: THandle): Boolean; begin if FGlobalBeginScene = 0 then begin FCanvasHelper.SetContext(Context); FCanvasHelper.BeginRender; TTextLayoutNG.BeginRender; end else begin FCanvasHelper.Flush; FCanvasHelper.SetContext(Context); FContext.SetMatrix(TMatrix3D.Identity); FContext.SetContextState(TContextState.cs2DScene); FContext.SetContextState(TContextState.csAllFace); FContext.SetContextState(TContextState.csZWriteOff); FContext.SetContextState(TContextState.csZTestOff); end; Inc(FGlobalBeginScene); FSaveCanvas := FCurrentCanvas; if Assigned(FSaveCanvas) and FSaveCanvas.FClippingEnabled then FSavedScissorRect := FCanvasHelper.ScissorRect; FCurrentCanvas := Self; Result := inherited DoBeginScene(AClipRects) and Assigned(FContext) and FContext.BeginScene; if Result then begin FClippingEnabled := False; FCurrentClipRect := TRect.Create(0, 0, Width, Height); FCanvasHelper.ResetScissorRect; FCanvasHelper.UpdateDrawingMode; end; end; В частности из условия второго и последующих вхождений в DoBeginScene: if FGlobalBeginScene = 0 then ... else ... выходит, что если вошли второй раз, то происходит какой-то FCanvasHelper.Flush куда-то. Возможно и суммарная картинка отобразится. Надо пробовать. Но скорее всего сначала все-таки промелькнет первая отрисованная сцена, а за ней вторая, но уже без изменений в первой сцене. Да, для одновременного рисования на одной канве наверное нужны методы блокировки части изображения. По-моему такие то ли в winapi, то ли в gdi видел.
  6. AlexG, спасибо за столь развернутый ответ =) Выходит, что в каком-то приближении отрисовку в FMX можно назвать потокобезопасной, но не многопоточной. Т.е. AV, как в VCL, не произойдет, но лаги быть могут.
  7. Вы про ALOOPER_POLL_ERROR на андроиде? Да, видимо андроид сам ограничивает этот процесс и мы никогда не узнаем, что будет, если эту проверку в нем убрать. Но что будет происходить на других платформах? На windows и mac os x я не заметил никаких глюков. Может быть при интенсивной отрисовке и будут артефакты (наподобие тех, когда отключаешь вертикальную синхронизацию в играх или двойную буферизацию на компоненте на форме), но их, наверное, можно избежать - например, один поток рисует на одной половине, другой на другой. Кто-нибудь сталкивался с более фатальными ошибками при отрисовке из НЕглавного потока без синхронизации?
  8. Спасибо, интересные подробности про андроид и яву. Я пока только под настольный mac os x пробую и только с контролами FMX. Собственно про это и вопрос - а нужно ли? Времена VCL-ной однопоточной отрисовки в этом случае прошли. Вся начинка FMX уже другая. Так вот Может я хочу свой (не главный) поток для отрисовки. Или может быть даже два потока. А не синхронизировать все через TThread.Synchronize. Поэтому и спрашиваю, можно ли так?)
  9. Никак не пойму, это слишком сложный или слишком глупый вопрос?) Кто-нибудь, ответьте, пожалуйста!
  10. Всем известно, что используя Vcl под Windows нельзя делать делать отрисовку не из главного потока ввиду особенностей канвы и vcl в целом. Как ведет себя Firemonkey в этом случае на разных платформах? Может уже можно делать эти вещи из других потоков? (опустим то, что это может привести к размазанности логики отрисовки). Пробовал манипулировать ProgressBar-ом из потока - вроде никаких ошибок не было. Нашел ответ от Brovin Yaroslav, Получается под андроидом это в порядке вещей или UI Thread = Main Thread?
  11. Нет-нет, сейчас проверил. Связывается только по имени всех параметров, кроме первого и по имени метода. Причем попробовал тип WebFrame в объявлении заменить на NSURL и делегат все равно вызвался. Спасибо)
  12. О чудо! Оно работает) Спасибо, Ярослав! Я думал, что связывание происходит только по имени метода. Для полной ясности хотелось бы еще уточнить, потому что не очень понятен принцип перевода. Первый параметр (webView1 для которого, кстати, не важно имя) является Self-ом, который передается неявно в ObjC, но у нас он выделен явно? В этом случае можно ли использовать дельфевый Self? (Скорее всего можно, но все же) Все-таки что означает первая часть определения, до имени метода: - (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id < WebPolicyDecisionListener>)listener То, что webView является первым параметром, а webView: началом имени или есть какой-то еще смысл?
  13. Вы имеете ввиду вот так?) constructor TWebViewDelegate.Create; begin inherited Create; end; Это какой-то хак? Попробовал, но ничего не изменилось(
  14. Помогите портировать интерфейсы для реализации делегата для WebView.setPolicyDelegate, с помощью которого можно запрещать или переопределять переходы по ссылкам. Отталкивался от хелпа эпла. Реализовал вроде как все, что нужно. Страница гугла открывается, но колбэк делегата не вызывается. unit MainFormUnit; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, Macapi.AppKit, Macapi.CocoaTypes, Macapi.Foundation, Macapi.ObjectiveC, FMX.StdCtrls, Posix.Stdlib, Macapi.CoreFoundation, FMX.Platform.Mac, System.Generics.Collections; type WebFrameClass = interface(NSObjectClass) ['{7BE750C8-DFEC-4870-851A-12DBCB0B78F6}'] end; WebFrame = interface(NSObject) ['{BCFA04BE-41AB-4B78-89C0-3330F12C7695}'] procedure loadRequest(request: NSURLRequest); cdecl; end; TWebFrame = class(TOCGenericImport<WebFrameClass, WebFrame>) end; WebViewClass = interface(NSViewClass) ['{0D9F44B7-09FD-4E35-B96E-8DB71B9A2537}'] {class} function canShowMIMEType(MIMEType: NSString): Boolean; cdecl; end; WebView = interface(NSView) ['{C36D8016-2FCB-49F0-BA1C-C9913A37F9AC}'] procedure clos; cdecl; procedure setPolicyDelegate(delegate: Pointer); cdecl; procedure setHostWindow(hostWindow: NSWindow); cdecl; function initWithFrame(frame: NSRect; frameName: NSString; groupName: NSString): Pointer; cdecl; function mainFrame: WebFrame; cdecl; end; TWebView = class(TOCGenericImport<WebViewClass, WebView>) end; WebPolicyDecisionListener = interface(IObjectiveC) ['{2AD8355D-6C57-410D-A4F4-230C90B6D799}'] procedure download; cdecl; procedure ignore; cdecl; procedure use; cdecl; end; WebViewDelegate = interface(IObjectiveC) ['{5B66FF5F-DA92-48D3-A715-C89A68AA8995}'] procedure decidePolicyForNavigationAction(actionInformation: NSDictionary; request: NSURLRequest; frame: WebFrame; listener: WebPolicyDecisionListener); cdecl; end; TWebViewDelegate = class(TOCLocal, WebViewDelegate) procedure decidePolicyForNavigationAction(actionInformation: NSDictionary; request: NSURLRequest; frame: WebFrame; listener: WebPolicyDecisionListener); cdecl; end; TForm1 = class(TForm) Button1: TButton; procedure FormCreate(Sender: TObject); public MyWebView: WebView; MyDelegate: TWebViewDelegate; end; var Form1: TForm1; implementation {$R *.fmx} procedure TForm1.FormCreate(Sender: TObject); var PWebView: Pointer; FwkMod: HMODULE; urlStr: NSURL; urlreq: NSURLRequest; MyView: NSView; const WebKitFWK: string = '/System/Library/Frameworks/WebKit.framework/WebKit'; begin FwkMod := System.SysUtils.LoadLibrary(PWideChar(WebKitFWK)); PWebView := TWebView.Alloc.initWithFrame(MakeNSRect(10, 10, 500, 500), nil, nil); MyWebView := TWebView.Wrap(PWebView); MyWebView.setAutoresizingMask(NSViewHeightSizable or NSViewWidthSizable); //MyWebView.setHostWindow(MyNSWindow); MyView := WindowHandleToPlatform(Form1.Handle).View; MyView.addSubview(MyWebView); MyDelegate := TWebViewDelegate.Create; MyWebView.setPolicyDelegate((MyDelegate as ILocalObject).GetObjectID); urlStr := TNSURL.Wrap(TNSURL.Alloc.initWithString(NSSTR('http://www.google.com/'))); urlreq := TNSURLRequest.Wrap(TNSURLRequest.Alloc.initWithURL(urlstr)); MyWebView.mainFrame.loadRequest(urlreq); urlStr.release; urlreq.release; end; { TWebViewDelegate } procedure TWebViewDelegate.decidePolicyForNavigationAction( actionInformation: NSDictionary; request: NSURLRequest; frame: WebFrame; listener: WebPolicyDecisionListener); begin MessageDlg('hi', TMsgDlgType.mtInformation, [TMsgDlgBtn.mbOK], 0); end; end. Также не совсем понятно, где должен располагаться метод webView:decidePolicyForNavigationAction:request:frame:decisionListener. В документации он объявлен как: - (void)webView:(WebView *)webView decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id < WebPolicyDecisionListener>)listener Т.е. похоже на то, что он должен быть методом класса WebView? Или же методом произвольного класса делегата? И еще, я так понимаю, что полное имя этого метода webView:decidePolicyForNavigationAction:request:frame:decisionListener, то есть объявляя его как decidePolicyForNavigationAction возможно мы лишаем mac os возможности найти его. Но как же тогда объявить его полностью?
  15. Можно использовать класс TUserInifile из модуля Apple.Inifiles, который был в XE4 если не ошибаюсь. Он хранит настройки персонально для каждого пользователя в plist-ах (в ~/Library/Preferences) используя класс NSUserDefaults
×
×
  • Создать...