7

これは Android SDK に関してはあまり意味がないかもしれませんが、C++ では、他のクラス/オブジェクトを宣言して初期化する場所として main.cpp (および特に main() 関数) を維持することに慣れています。私のアプリケーションがそれらのクラスで行われること。その後、戻って main.cpp の内容を確認することはありません。しかし、Java や Android SDK では、メイン アクティビティで多数のメソッドをオーバーライドする必要があり、そのすべてが 1 つのファイルで行われます。例:

私のプロジェクトには MainActivity.java と SomeTest.java ファイルがあります。最初はアクティビティを拡張するデフォルトの MainActivity クラスで、SomeTest.java には新しいスレッドを宣言して実行するクラスが含まれています。MainActivity.java から SomeTest クラスを初期化し、アクティビティのハンドルをパラメーターとして渡します。

SomeTest test = new SomeTest(MainActivity.this);

MainActivity へのハンドルを持っているので、この新しく作成されたスレッドからすべてを実行します。UI を更新する必要がある場合は、runOnUiThread() を使用して新しい ListView (たとえば) を作成し、メイン レイアウトに表示します。getWidth() と getHeight() は ListView が実際に画面に表示されます。私にとって、MainActivity からそのスレッドへのそのような接続 (場合によっては「コールバック」) を作成することはお勧めできません。

スレッド内にonWindowFocusChanged() のようなメソッドを保持し、MainActivity.java にまったく触れない方法はありますか?

おっしゃるとおり、あまり意味がないかもしれません。

4

4 に答える 4

4

onWindowFocusChanged()のようなメソッドをスレッド内に保持し、MainActivity.javaにまったく触れないようにする方法はありますか?

onWindowFocusChanged()コールバックメソッドです。活動に呼ばれます。これは変更できません。

そして、MainActivityへのハンドルを持って、この新しく作成されたスレッドからすべてを実行します。

それは一般的に良い考えではありません。たとえば、バックグラウンドスレッドを使用して、ファイルまたはデータベースから一部のデータをロードすることは、完全に合理的です(ただし、を使用するLoaderか、より適切なAsyncTask場合があります)。ただし、通常、バックグラウンドスレッドは、「新しく作成されたListViewの幅と高さ」などを認識したり気にしたりする必要はありません。

いくつかのロジックをアクティビティから他のクラスに移行することは確かに歓迎されています。そのために、フラグメントやカスタムビューなどの特定のフレームワークを使用する場合があります。ただし、クラス構造はスレッドモデルによって駆動されるべきではありません。たとえば、冒頭陳述に戻りましょう。

C ++では、main.cpp(特にmain()関数)を他のクラス/オブジェクトを宣言して初期化する場所として維持し、その後、アプリケーションがそれらのクラスで行うすべてのことを行うことに慣れています。

ただし、C ++では、2つのクラスしか持たないことに縛られているとは言えません。そのうちの1つは、何らかのバックグラウンドスレッドで動作しています。たまたまバックグラウンドスレッドを使用するクラスがあるかもしれませんが、クラス構造の背後にある原動力は「バックグラウンドスレッドがあります」ではなく、「XYZロジックを再利用したい」または「欲しい」です。戦略パターンをサポートするためにクラス階層を使用する」など。

于 2013-02-22T14:12:55.997 に答える
1

個人的に言えばContext、Android SDK から取られたアイデアは厄介なようです。あなたが説明していることは、 に対するあまりにも多くの責任から来ていますActivity。そのため、単一のファイル内で多くのことを追跡する必要があります(Activityのライフサイクル、Context表示するためのインスタンスの取得Dialogなど)。完璧な解決策はないと思いますが、以下を使用することをお勧めします。

  • Fragment画面(およびロジックなど)を別々の部分に分割するのに役立つサブクラス
  • AndroidAnnotationsRoboGuiceOttoなどのサードパーティのフレームワーク/ライブラリは、スパゲッティ コードを回避するのに最適なツールです。
于 2013-02-22T14:31:38.677 に答える
0

別のクラスからUIの更新を実行する場合は、更新する必要のあるビューを渡すAsyncTaskの使用を検討してください。例が必要な場合はお知らせください

于 2013-02-22T14:13:53.823 に答える
0

私はすべてを読み、あなたの声明を理解しています。あなたがしばらくの間プログラミングを行っていることがわかりますが、どうやらAndroidから始めたばかりのようです。以前に多くの組み込みシステムを行ったので、次のようなソフトウェアを持つという概念を完全に理解しています:

void run(){
    object.setup();
    while(true){
        otherObject.run();
    }
}

しかし、質問のロジックには根本的な欠陥が 1 つあります。

Android プログラミングは、C++ やコンピューター プログラミングとは異なるプログラミング パラダイムであるため、他のパラダイムの優れたプラクティスを想定するのではなく、Android 固有のパラダイムを理解する必要があります。

あなたからの引用: create and show a new ListView (for example) on my main layout. I want to get the width and height of the newly created Listview, for what I have to override onWindowFocusChanged().

そのことから、Android コンテキストでは推奨されない方法で Android のことを実際にやろうとしていることがわかります。XML レイアウトから簡単に実装できsetContentView(int)、Activity onCreate を使用して任意のスレッド化 (AsyncTaskLoader) フレームワークをインスタンス化し、バックグラウンドでデータをロードして UI に戻すことができる ListView。

これは、すべてのコードが 1 つのファイルにダンプされて混乱するという意味ではありません。この小さな例は、ローダー コールバックを実装するアクティビティ、ローダーとは別のクラス、データ ロード作業とは別のクラス、データ アダプターとは別のクラスを実装するアクティビティで実行できます。ライフサイクルの適切なタイミングでこれらのクラスを管理し、呼び出す必要がなくonWindowFocusChanged()、きちんと整理されたコードを保持できます。

それとは別に、通常は巧妙に書かれていて正しいので、CommonsWareの回答を参照してください。

于 2013-02-22T14:31:24.197 に答える