2017-09-06 9 views
1

Javaのnoobはここに!私は、私が書いているAndroidアプリに仕上げのタッチを入れるのに苦労している。基本的にRSSリーダーです。非同期タスクはRSSフィードをフェッチします。それが解析され、最終的に私がしたいのは、解析されたRSSでアクティビティのListView要素を更新することです。Javaクラスの周りにデータを渡す

fetcherのタストは非同期であるため、独自のクラスにあるため、UIを直接更新することはできません(私は信じています)。

マイonPostExecuteの宣言は次のとおりです。

public class getNews extends AsyncTask<String , Void ,String> { 
    String server_response; 
    // url fetch stuff is in here 
} 

protected void onPostExecute(String s) { 
      super.onPostExecute(s); 
      FullscreenActivity.updateNews(server_response) 

     } 

FullscreenActivity.javaクラスはserver_responseを受け取り、罰金、それを解析します

public static void updateNews(String newsXML) { 

// stuff goes on here, and I end up with a string array called headlines that 
// contains the news headlines 

} 

私はリストビューを更新しようとすると、私の問題が来ます。私はこの

ListView m_listview = (ListView) findViewById(R.id.ListViewRight); 

ようupdateNewsでそれを実行しようとした場合、私は非静的メソッドを言うfindViewById下の赤い波状を取得...静的コンテキストから参照することはできません。

私はupdateNews()を非静的にすると、同じことを言っているonPostExecuteルーチンのupdateNewsの下に赤いウィッグが表示されます。

私のサブルーチンの宣言で、私の非同期受信機、パーサ、およびListViewからXMLを取得するのに必要なフレーバーの組み合わせは何ですか?

私は静的、私的、公衆などと全く混同されています。彼らについて読むことを試みた後でさえ、私は誰も賢明ではありません!

プロジェクトがあれば、Githubに投稿することができます。私はそれがまさにJavaがどのように見えるかの輝かしい例ではないと確信しています!事前に

おかげで、 イアン

+0

ご協力いただきありがとうございます。これに続いて、自分のアクティビティクラスにいくつかの行を追加することでコードを作成しました。私は以下で説明します。ここに十分な文字がありません... – Iain

答えて

1

fetcherのタストは非同期であるため、独自のクラスになっているため、UIを直接更新することはできません(私は信じています)。

これは、「直接」とは何を意味するかによって異なります。 UIスレッド(別名メインスレッド)以外のスレッドからViewを更新しようとすると、Androidフレームワークがアプリをクラッシュさせることは事実です。しかし、AsyncTaskが実行されます。 onPostExecute()がUIスレッド上にあるので、このメソッド内のビューを更新するのは完全に有効です。

あなたのタスクは「独自のクラス」なので、デフォルトでは更新するビューにアクセスすることはできませんが、にはにアクセスするように設定できます。

私は静的、私的、公衆などと全く混同されています。それらについて読むことを試みた後でさえ、私は誰も賢明ではありません!

まず者がprivatepublicについて話しましょう。これらはアクセスレベル修飾子として知られており、詳細についてはこちらをご覧ください。https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

ただし、簡単な要約で十分です。何かがprivateなら、それはそれを使用できる唯一のオブジェクトが同じタイプのものであることを意味します。何かがpublicであれば誰でもそれを使うことができます。

staticが異なります。このキーワードは、それを適用した変数またはメソッドが "インスタンス"メンバー(staticキーワードのないもの)か "クラス"メンバー(staticキーワードのもの)かどうかを定義します。繰り返しますが、ここで詳しく読むことができます:https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html

また、簡単な要約で十分です。何かがstaticの場合、それはそのクラスのすべてのインスタンスによって共有されるを意味します。つまり、そのクラスの特定のインスタンスではなく、そのクラスの「アイデア」に関連しています。それ以外の場合、変数またはメソッドはクラスの特定のインスタンスにのみ関連します。戻ってあなたの実際の例に行く

は、我々はこの方法について話すことができます。

public static void updateNews(String newsXML) { 
    ... 
} 

この方法は、それがFullscreenActivityのすべてのインスタンスで共有さを意味し、staticです。これは誰でも使用できることを意味するpublicです。だからあなたのAsyncTaskは簡単

FullscreenActivity.updateNews(server_response); 

を書き込むことによって、それを呼び出すことができますしかし、あなたは、Androidでの活動で作業しているとき、あなたは一般的なアイデアと活動の特定のインスタンスの動作と、一般的に懸念している、とではありませんあなたの活動。つまり、ユーザーの電話で起動して実行中のアクティビティの画面を更新したい場合は、すべてのFullscreenActivityインスタンスが存在する可能性があります。

ですから、このメソッドは非staticにする必要があります。

public void updateNews(String newsXML) { 
    ... 
} 

今、このメソッドは非静的であることを、あなたはそれを呼び出すためにFullscreenActivityインスタンスを必要としています。あなたがこれを書くようになる何か:これを行うには

activity.updateNews(server_response); 

一つの簡単な方法は、あなたのAsyncTaskのコンストラクタにあなたの活動を渡すことです。今

public class GetNews extends AsyncTask<String, Void, String> { 

    private FullscreenActivity activity; 

    public GetNews(FullscreenActivity activity) { 
     this.activity = activity; 
    } 

    ... 

    protected void onPostExecute(String s) { 
     super.onPostExecute(s); 
     activity.updateNews(server_response); 
    } 
} 

、あなたのGetNewsインスタンスを作成し、むしろnew GetNews()を書くよりも、あなたはnew GetNews(this)(あなたがこのコードを実行するときにFullscreenActivityの中にいると仮定して)書き込むことができます。

0

静的メソッドはなく、インスタンスと、クラスと関連しているので、

public static void updateNews(String newsXML) { 
    //dunno what do you want to do here  
} 

が動作しないことまあ最悪。

まずはインスタンスをAsyncTaskに渡します。

public class GetNews extends AsyncTask<String , Void ,String> { 
    String server_response; 
    FullscreenActivity activity; 
    public GetNews(FullscreenActivityactivity) { 
     this.activity = activity; 
    } 
} 

ですから、あなたがその

protected void onPostExecute(String s) { 
      super.onPostExecute(s); 
      if (activity != null) 
       activity.updateNews(server_response) 
} 

アップデートのようにやりたいことができます

public static void updateNews(String newsXML) {} 

static

public void updateNews(String newsXML) {} 

を行います

について

ListView m_listview = (ListView) findViewById(R.id.ListViewRight); 

なぜあなたActivityクラスのフィールドとしてm_listviewを作り、onCreate方法でそれをインスタンス化するには?

public class FullscreenActivityactivity extends Activity { 
    private ListView m_listview; 
     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      m_listview = (ListView) findViewById(R.id.ListViewRight); 
     } 
} 
0

findViewByIdは非静的メソッドです。つまり、Activityのインスタンスで呼び出す必要があり、静的メソッドで呼び出すことはできません。

一般に、あなたのアクティビティを更新するための静的メソッドは動作しません。また、動作させるためにハックする方法は悪いアイデアとみなされ、一般にメモリリークにつながります。あなたのAsyncTaskはあなたのアクティビティの内部クラスでなければなりません(その場合、非静的な更新関数を呼び出すことができます)、または終了したらそれを呼び出すインターフェイスを渡す必要があります(そして、あなたのアクティビティはupdateListを呼び出すインターフェイスに渡す必要があります) 。

+0

おそらくあなたは "内部クラス"を意味し、 "サブクラス"を意味しません。 –

+0

ありがとう、ありがとう。 –

0

ご協力いただきありがとうございます。これに続いて、私は私の活動のクラスに数行を追加することにより、作業の私のコードを持っている:

public class FullscreenActivity extends AppCompatActivity { 
    public static ListView m_listview; 
    public static Activity myThis; 

その後のonCreateでは、私が追加しました:

m_listview = (ListView) findViewById(R.id.ListViewRight); 
myThis = this; // seems messy? 

私のリストビューを更新することができますどの私がする必要があるとき:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(myThis, R.layout.listview_row_layout, R.id.firstLine, headlines); 
m_listview.setAdapter(adapter);` 

私はそれをつけるつもりです。私は何年もJavaとAndroidの開発を学びたいと思っていましたが、今はそうするプロジェクトがあります。

私の背景は、多くの古い言語(基本的な、ほとんど)とPerlのようなスクリプト言語です。まだJavaが奇妙な獣だと思っていますが、私の年にもより良くなることを望んでいます! old_dog.new_tricks.teach(); :)

関連する問題