Androidの非同期処理でネットワークエラー発生
Androidから、AsyncTaskを使用してURLにアクセスし、
外部DBのMySQLから引っ張ってきたデータをXML形式に変換したものを
取得したいと思っています。
一通り処理を作成し、実験的にデータを取得してみたのですが、
問題なく取得できるものと、途中でNetworkOnMainThreadExceptionが発生するものが
出てきてしまいました。
具体的には、下記のようなテーブルのデータを全カラム分取得し、
XML形式に変換しています。
【取得に成功したテーブル】
カラム数:3
内訳:INT型→1カラム、VARCHAR型→2カラム
一度に取得するデータ数:7行
【取得に失敗するテーブル】
カラム数:22
内訳:INT型→7カラム、CARCHAR型→12カラム、
TEXT型→1カラム、DATETIME型→2カラム
一度に取得するデータ数:最大10行
NetworkOnMainThreadExceptionが発生するタイミングは、
XMLデータを取得したタイミングではなく、
取得したXMLをデータ格納用オブジェクトに入れて
ArrayListに蓄積しているタイミングです。
データが取得できているテーブルもあるので、
AsyncTaskの使い方が間違っているわけではないと思うのですが
NetworkOnMainThreadExceptionが発生する原因を調べてみても、
AsyncTaskを使っていないから、というものしか出てこないので、
原因がさっぱりわかりません。
AsyncTaskの使い方で何か間違っている箇所があるのか、
そもそもAsyncTaskで取得させるデータ量に制限があるのか、
何かの指定をすればうまくできるものなのか、
何か思い当たることがあれば、教えていただきたいと思っています。
【AsyncTaskをextendsした自作クラス】
public class AsyncXmlLoader extends AsyncTask<String, Integer, InputStream> {
public interface AsyncCallback {
void preExecute();
void postExecute(InputStream result);
void progressUpdate(int progress);
void cancel();
}
private AsyncCallback asyncCallback = null;
public AsyncXmlLoader(AsyncCallback asyncCallback) {
this.asyncCallback = asyncCallback;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
asyncCallback.preExecute();
}
@Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
asyncCallback.progressUpdate(progress[0]);
}
@Override
protected void onPostExecute(InputStream result) {
super.onPostExecute(result);
asyncCallback.postExecute(result);
}
@Override
protected void onCancelled() {
super.onCancelled();
asyncCallback.cancel();
}
@Override
protected InputStream doInBackground(String... uri) {
InputStream inputStream = null;
try {
// URLクラスのインスタンス作成
URL url = new URL(uri[0]);
// コネクション接続
URLConnection connection = url.openConnection();
// ストリームを取得
inputStream = connection.getInputStream();
} catch (MalformedURLException e) {
Log.e("AsyncXmlLoader", e);
} catch (IOException e) {
Log.e("AsyncXmlLoader", e);
} catch (Exception e) {
Log.e("AsyncXmlLoader", e);
}
return inputStream;
}
}
【実際にデータを取得している箇所】
public class MainActivity extends ActionBarActivity {
private final String URL = "http://hoge.jp/test.php";
private TextView testTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// TextViewを取得
testTextView = (TextView)findViewById(R.id.textViewTest);
// XMLからカテゴリデータを取得
AsyncXmlLoader xml = new AsyncXmlLoader(new AsyncXmlLoader.AsyncCallback() {
// 実行前
public void preExecute() { }
// 実行後
public void postExecute(InputStream result) {
if (result == null) {
Log.e("AsyncCallback", "データ取得失敗");
return;
}
// XMLのデータを取得して画面に表示
BufferedReader br = new BufferedReader(new InputStreamReader(result));
StringBuilder sb = new StringBuilder();
String line;
try {
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
Log.e("AsyncCallback", e);
}
testTextView.setText(sb.toString());
}
// 実行中
public void progressUpdate(int progress) { }
// キャンセル
public void cancel() { }
});
// 処理を実行
xml.execute(URL);
}
}
お知恵を貸していただきたいと思います。
どうぞよろしくお願いいたします。