javaで関数をパラメータとして渡す
質問
私はAndroidフレームワークとJavaに慣れてきており、ネットワークコードの大部分を処理する一般的なquot;NetworkHelper"クラスを作りたいと考えています。
私は、developer.android.com からのこの記事に従って、私のネットワーキングクラスを作成しました。 http://developer.android.com/training/basics/network-ops/connecting.html
コードです。
package com.example.androidapp;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.util.Log;
/**
* @author tuomas
* This class provides basic helper functions and features for network communication.
*/
public class NetworkHelper
{
private Context mContext;
public NetworkHelper(Context mContext)
{
//get context
this.mContext = mContext;
}
/**
* Checks if the network connection is available.
*/
public boolean checkConnection()
{
//checks if the network connection exists and works as should be
ConnectivityManager connMgr = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected())
{
//network connection works
Log.v("log", "Network connection works");
return true;
}
else
{
//network connection won't work
Log.v("log", "Network connection won't work");
return false;
}
}
public void downloadUrl(String stringUrl)
{
new DownloadWebpageTask().execute(stringUrl);
}
//actual code to handle download
private class DownloadWebpageTask extends AsyncTask<String, Void, String>
{
@Override
protected String doInBackground(String... urls)
{
// params comes from the execute() call: params[0] is the url.
try {
return downloadUrl(urls[0]);
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
// Given a URL, establishes an HttpUrlConnection and retrieves
// the web page content as a InputStream, which it returns as
// a string.
private String downloadUrl(String myurl) throws IOException
{
InputStream is = null;
// Only display the first 500 characters of the retrieved
// web page content.
int len = 500;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 );
conn.setConnectTimeout(15000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
int response = conn.getResponseCode();
Log.d("log", "The response is: " + response);
is = conn.getInputStream();
// Convert the InputStream into a string
String contentAsString = readIt(is, len);
return contentAsString;
// Makes sure that the InputStream is closed after the app is
// finished using it.
} finally {
if (is != null) {
is.close();
}
}
}
// Reads an InputStream and converts it to a String.
public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException
{
Reader reader = null;
reader = new InputStreamReader(stream, "UTF-8");
char[] buffer = new char[len];
reader.read(buffer);
return new String(buffer);
}
// onPostExecute displays the results of the AsyncTask.
@Override
protected void onPostExecute(String result)
{
//textView.setText(result);
Log.v("log", result);
}
}
}
アクティビティクラスでは、このように使っています。
connHelper = new NetworkHelper(this);
...
if (connHelper.checkConnection())
{
//connection ok, download the webpage from provided url
connHelper.downloadUrl(stringUrl);
}
私が抱えている問題は、何らかの方法でアクティビティに戻るコールバックを作成する必要があり、それは "downloadUrl()"関数で定義可能であるべきだということです。例えば、ダウンロードが終了すると、アクティビティ内の public void "handleWebpage(String data)" 関数は、パラメータとしてロードされた文字列で呼び出されます。
私はいくつかググって、この機能を達成するために何らかの形でインターフェイスを使用する必要があることを発見しました。いくつかの同様の stackoverflow の質問/回答を確認した後、私はそれを動作させることができず、私がインターフェイスを適切に理解しているかどうかわからない。 どのように私はJavaでパラメータとしてメソッドを渡すのですか? 正直なところ、匿名クラスを使用することは私にとって新しいことであり、私は言及されたスレッドのサンプルコードスニペットをどこで、どのように適用すべきかがよくわかりません。
私の質問は、どのようにコールバック関数を私のネットワーククラスに渡し、ダウンロードが終了した後にそれを呼び出すことができるかということです。インターフェイスの宣言はどこに行くのか、implements キーワードやその他は? 私はJavaの初心者であることに注意してください(他のプログラミングのバックグラウンドを持っていますが)ので、私は全体の説明を感謝します。) ありがとうございます!
どのように解決するのですか?
コールバックインターフェースや、コールバックメソッドが抽象化された抽象クラスを使用する。
コールバックインターフェースの例です。
public class SampleActivity extends Activity {
//define callback interface
interface MyCallbackInterface {
void onDownloadFinished(String result);
}
//your method slightly modified to take callback into account
public void downloadUrl(String stringUrl, MyCallbackInterface callback) {
new DownloadWebpageTask(callback).execute(stringUrl);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//example to modified downloadUrl method
downloadUrl("http://google.com", new MyCallbackInterface() {
@Override
public void onDownloadFinished(String result) {
// Do something when download finished
}
});
}
//your async task class
private class DownloadWebpageTask extends AsyncTask<String, Void, String> {
final MyCallbackInterface callback;
DownloadWebpageTask(MyCallbackInterface callback) {
this.callback = callback;
}
@Override
protected void onPostExecute(String result) {
callback.onDownloadFinished(result);
}
//except for this leave your code for this class untouched...
}
}
2番目のオプションはさらに簡潔です。のように "onDownloadedイベント"のための抽象メソッドを定義する必要さえありません。
onPostExecute
はまさに必要なことを行ってくれるからです。単に
DownloadWebpageTask
の中にある無名のインラインクラスで
downloadUrl
メソッド内に無名のインラインクラスを作成します。
//your method slightly modified to take callback into account
public void downloadUrl(String stringUrl, final MyCallbackInterface callback) {
new DownloadWebpageTask() {
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
callback.onDownloadFinished(result);
}
}.execute(stringUrl);
}
//...
関連
-
keytool error: java.io.FileNotFoundException: cacerts (アクセス拒否されました。)
-
Java JDKのダイナミックプロキシ(AOP)の使用と実装の原理分析
-
ApiModel と @ApiModelProperty の使用法
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] Javaはパラメータのデフォルト値をサポートしていますか?
-
[解決済み] Bash関数にパラメータを渡す
-
[解決済み】JavaScriptの関数にデフォルトのパラメータ値を設定する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
mvn' は、内部または外部のコマンド、操作可能なプログラムまたはバッチファイルとして認識されません。
-
型に解決できない エラー解決
-
Springの設定でxsdファイルのバージョン番号を設定しない方が良い理由
-
プロジェクトの依存関係を解決できない。
-
ApplicationContextの起動エラーです。条件レポートを表示するには、アプリケーションを'de'で再実行します。
-
ajax コミット リソースの読み込みに失敗しました: サーバーはステータス 400 で応答しました ()
-
Javaジェネリックを1つの記事で
-
セミコロン期待値エラー解決
-
Java の double データ型における 0.0 と -0.0 の問題
-
Spring Bootは、Tomcatの組み込みのmaxPostSizeの値を設定します。