1

Delphi XE5 を使用して Android 用の簡単なゲームを作成しています。PNG と Jpeg のリソースがいくつかあります。プログラムがすべてのリソースをロードしている間、ロード画面を表示したいと考えていました。

しかし、Android スレッド内に TBitmap.LoadFromFile または TBitmap.LoadFromStream コードを配置すると、アプリがすぐに終了して Launcher に戻ることがわかりました。デバッグ モードでは、Delphi は例外をキャッチしません。(コードは Windows では完全に機能し、Android ではスレッドなしで機能します)

何が起こったのかを確認するために logcat を開く必要がありました。

私の質問は、Delphi XE5 を使用して Android のロード画面を作成する方法はありますか? 画像がメモリにロードされている間、進行状況画面が表示されるようにします。


問題を特定するためだけにテスト プロジェクトを作成しました。結果は次のとおりです。LoadFromFile はスレッド 1 です。ログはスレッドが実際に実行されたことを示していますが、その後例外が発生しました???

Logcat スクリーンショット:ログキャットの結果 ソース コード: http://www.pockhero.com/wp-content/uploads/2013/10/threadtest1.7z

4

2 に答える 2

4

これはどうやら次のアップデートで修正されるはずのバグです。コードに修正を適用するには、次のプロシージャを宣言します。

uses
  Androidapi.NativeActivity,
  Posix.Pthread;


procedure MyEndThreadProc(ExitCode:Integer);
var
  PActivity: PANativeActivity;
begin
    PActivity := PANativeActivity(System.DelphiActivity);
    PActivity^.vm^.DetachCurrentThread(PActivity^.vm);
    pthread_exit(ExitCode);
end;

System.Classes から EndThreadProc に割り当てます。

procedure TForm1.FormCreate(Sender: TObject);
begin
  EndThreadProc := MyEndThreadProc;
end;

この修正により、たとえば、スレッドを次のように設定できます

FreeOnTerminate := true;

そして、このようなコードはもうアプリケーションをクラッシュさせません:

TYourThread.Create(something, somethingelse).Start;

このソリューションを Embarcadero フォーラムに投稿した Antonio Tortosa の功績を称えなければなりません。

于 2014-01-23T20:15:27.147 に答える
1

多くのテストと同僚の助けを借りて、同僚と私は問題を解決しました。解決策は、スレッドを終了せず、スレッドを実行し続けることです。

私はこれが少し奇妙であることを知っています。FreeOnTerminate をオフにしようとしましたが、実際のスレッドではなく、スレッド オブジェクトのみを制御します。同期された通話が同期されていないように見えます。ビットマップが実際にいつ、どこで使用またはコピーされているかはわかりません。いずれにせよ、Delphi でコンパイルされた Android lib コードはメイン スレッドで実行されないため、別の GUI スレッドがどこかにある可能性があります。

これが作業コードです。

procedure TBitmapThread.Execute;
begin
  inherited;
  BeforeExecute;
  try
    fBitmap := TBitmap.CreateFromFile(TPath.Combine(TPath.GetDocumentsPath, 'koala.jpg'));
    // Sleep(2000);
    Synchronize(UpdateImage);
    // Keep the thread running
    while not Terminated do
    begin
      Sleep(100);
    end;
    fBitmap.Free;
  except
    on E:Exception do
    begin
      Log.d('TestThread Exception: ' + E.message);
    end;
  end;
  AfterExecute;
end;
于 2013-10-22T03:21:49.190 に答える