現在、XMLPullParser を使用して駅の API からページを解析しています。Androidの新しいバージョンに追いつくために、非同期タスクを使用してこれを行っています。
現在、XML 文字列をクラスにハードコーディングしており、結果はリストビューに表示されます。
ただし、baseURL を追加して、ユーザーが入力したクエリを最後に追加するのに問題があります。次の行に沿ったコードを使用して非同期タスクを使用する前に、これを行うのに問題はありませんでした。
public void StationDetails(){
//--- Search button ---
Button btnSearch = (Button) findViewById(R.id.btnSearch);
btnSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//--- EditText View ---
EditText input = (EditText) findViewById(R.id.inputStation);
StringBuilder URL = new StringBuilder(baseURL);
URL.append(input);
String fullURL = URL.toString();
}
});
}
しかし、これを非同期メソッドに関連付けることはできません。私はオンラインで何も見つけられないようで、この問題について誰か助けていただければ幸いです。
ハードコード文字列を持つクラスは次のとおりです。
public class Realtime extends Activity {
// Irish Rail Site URL
private static final String baseURL = "http://api.irishrail.ie/realtime/realtime.asmx/getStationDataByNameXML?StationDesc=Malahide";
// XML TAG Name
private static final String TAG_ITEM = "objStationData";
private static final String TAG_ORIGIN = "Origin";
private static final String TAG_DEST = "Destination";
private static final String TAG_SCHARR = "Scharrival";
private static final String TAG_EXPARR = "Exparrival";
private static final String TAG_DIRECT = "Direction";
private static final String TAG_STAT = "Status";
private static final String TAG_TRAINTYPE = "Traintype";
private RealtimeListviewAdapter mAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.stations_realtime_layout);
ListView listView = (ListView) findViewById(R.id.listview);
mAdapter = new RealtimeListviewAdapter(this);
// set adapter
listView.setAdapter(mAdapter);
// use AsyncTask to parse the URL data
ParseTask task = new ParseTask(this);
task.execute(baseURL);
// --- Register the list view for long press menu options
registerForContextMenu(listView);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private class ParseTask extends
AsyncTask<String, Void, ArrayList<StationDetails>> {
private ProgressDialog dialog;
public ParseTask(Context c) {
dialog = new ProgressDialog(c);
}
@Override
protected void onPreExecute() {
dialog.setMessage("Loading Station Info...");
dialog.show();
}
@Override
protected ArrayList<StationDetails> doInBackground(String... params) {
String strUrl = params[0];
HttpURLConnection httpConnection = null;
InputStream is = null;
try {
URL url = new URL(strUrl);
httpConnection = (HttpURLConnection) url.openConnection();
httpConnection.setRequestMethod("GET");
httpConnection.setConnectTimeout(10000);
httpConnection.setReadTimeout(10000);
httpConnection.connect();
int responseCode = httpConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
is = httpConnection.getInputStream();
return parseNews(is);
}
} catch (Exception e) {
// TODO
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (httpConnection != null) {
httpConnection.disconnect();
httpConnection = null;
}
}
return null;
}
@Override
protected void onPostExecute(ArrayList<StationDetails> result) {
// set the result
mAdapter.setData(result);
// notify to refresh
mAdapter.notifyDataSetChanged();
// Close the progress dialog
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}
private ArrayList<StationDetails> parseNews(InputStream in)
throws XmlPullParserException, IOException {
ArrayList<StationDetails> newsList = new ArrayList<StationDetails>();
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser pullParser = factory.newPullParser();
pullParser.setInput(in, "UTF-8");
int eventType = pullParser.getEventType();
StationDetails item = null;
while (eventType != XmlPullParser.END_DOCUMENT) {
String tagName;
if (eventType == XmlPullParser.START_TAG) {
tagName = pullParser.getName();
if (tagName.equals(TAG_ITEM)) {
item = new StationDetails();
} else if (tagName.equals(TAG_ORIGIN)) {
if (item != null) {
item.mOrigin = pullParser.nextText();
}
} else if (tagName.equals(TAG_DEST)) {
if (item != null) {
item.mDestination = pullParser.nextText();
}
} else if (tagName.equals(TAG_SCHARR)) {
if (item != null) {
item.mSchArrival = pullParser.nextText();
}
} else if (tagName.equals(TAG_EXPARR)) {
if (item != null) {
item.mExpArrival = pullParser.nextText();
}
} else if (tagName.equals(TAG_DIRECT)) {
if (item != null) {
item.mDirection = pullParser.nextText();
}
} else if (tagName.equals(TAG_STAT)) {
if (item != null) {
item.mStatus = pullParser.nextText();
}
}
} else if (eventType == XmlPullParser.END_TAG) {
tagName = pullParser.getName();
if (tagName.equals(TAG_ITEM)) {
newsList.add(item);
item = null;
}
}
eventType = pullParser.next();
}
return newsList;
}
更新を編集
わかりました、ボタンの onClickListener に fullURL の stringbuilder を配置しました。今私が欲しいのは、ボタンがクリックされたときにタスクを実行することです。parsetask タスク、.execute などをこの clickListener に移動しました。ただし、これにより、リアルタイムのView.OnClickListenerが未定義であるというエラーが表示されます。クイックフィックスに従いますが、プロジェクトを実行すると、logcatにandroid.content.Contextにキャストできないというエラーが表示されます。
クイックフィックス後のコードのスニペットを次に示します。
searchBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Append user input to baseURL
StringBuilder URL = new StringBuilder(baseURL);
URL.append(userInput);
String fullURL = URL.toString();
// use AsyncTask to parse the URL data
ParseTask task = new ParseTask(this);
task.execute(fullURL);
}
});
public ParseTask(OnClickListener onClickListener) {
dialog = new ProgressDialog((Context) onClickListener);
}
そして私のlogcat:
私はまだこれを理解できず、誰の助けも大歓迎です