私はAndroidの開発にはかなり新しく、現在は複数の都市の明日の天気を表示するアプリを作成しようとしています。申し訳ありませんが、私はこの質問で使用するかもしれません。私が到達したい何Android。データベースからデータを取得し、ネットワーククエリを行います。実装方法
:
のAppは、DBから取得したデータにHTTPクエリを構築し、JSONレスポンスを取得し、リスト要素を形成し、その後、ローカルデータベースからデータを取得します。
私は現在持っているもの:SQLの機能を除いて
すべて。
ここに私の主な活動コードのスナップショットがあります。私はLoaderCallbacks<List<Weather>>
を使用して、必要なパラメータを持つURIをonCreateLoader(int i, Bundle bundle)
に作成し、HTTPクエリを送信してWeatherLoader(this, uriList)
でデータを取得し、List
のフォーム要素の結果をWeatherAdapter
とします。
public class WeatherActivity extends AppCompatActivity
implements LoaderCallbacks<List<Weather>>,
SharedPreferences.OnSharedPreferenceChangeListener {
private static final int WEATHER_LOADER_ID = 1;
private WeatherAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.weather_activity);
ListView weatherListView = (ListView) findViewById(R.id.list);
mEmptyStateTextView = (TextView) findViewById(R.id.empty_view);
weatherListView.setEmptyView(mEmptyStateTextView);
mAdapter = new WeatherAdapter(this, new ArrayList<Weather>());
weatherListView.setAdapter(mAdapter);
...
weatherListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
Weather currentWeather = mAdapter.getItem(position);
Uri forecastUri = Uri.parse(currentWeather.getUrl());
Intent websiteIntent = new Intent(Intent.ACTION_VIEW, forecastUri);
startActivity(websiteIntent);
}
});
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
LoaderManager loaderManager = getLoaderManager();
loaderManager.initLoader(WEATHER_LOADER_ID, null, this);
} else {
View loadingIndicator = findViewById(R.id.loading_indicator);
loadingIndicator.setVisibility(View.GONE);
mEmptyStateTextView.setText(R.string.no_internet_connection);
}
}
@Override
public Loader<List<Weather>> onCreateLoader(int i, Bundle bundle) {
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
String tempUnit = sharedPrefs.getString(
getString(R.string.settings_temp_unit_key),
getString(R.string.settings_temp_unit_default));
List<String> uriList = new ArrayList<>();
/***
*
* Here we input cities for which we want to see the forecast
*
* ***/
List<String> cities = new ArrayList<>();
cities.add("London,uk");
cities.add("Kiev,ua");
cities.add("Berlin,de");
cities.add("Dubai,ae");
//For each city in the list generate URI and put it in the URIs list
for (String city : cities){
Uri baseUri = Uri.parse(OWM_REQUEST_URL);
Uri.Builder uriBuilder = baseUri.buildUpon();
uriBuilder.appendQueryParameter("q", city);
uriBuilder.appendQueryParameter("cnt", "16");
uriBuilder.appendQueryParameter("units", tempUnit);
uriBuilder.appendQueryParameter("appid", "some_key");
uriList.add(uriBuilder.toString());
}
return new WeatherLoader(this, uriList);
}
@Override
public void onLoadFinished(Loader<List<Weather>> loader, List<Weather> weatherList) {
mAdapter.clear();
// If there is a valid list of forecasts, then add them to the adapter's
// data set. This will trigger the ListView to update.
if (weatherList != null && !weatherList.isEmpty()) {
mAdapter.addAll(weatherList);
}
}
@Override
public void onLoaderReset(Loader<List<Weather>> loader) {
mAdapter.clear();
}
見ての通り、都市はonCreateLoader(int i, Bundle bundle)
でList<String> cities = new ArrayList<>();
を経由して "ハードコードさ" です。だから、私は自分のアプリに都市のSQLストレージを実装することに決めました。私はContentProvider
とCursorAdapter
を使用して、アンドロイドアプリでSQL機能を実装する方法を知っています。
問題は何ですか?
私が正しい場合は、ローカルDBにクエリを作成する場合は、LoaderManager.LoaderCallbacks<Cursor>
を使用する必要があります。
残念ながら、現在のLoaderCallbacks<List<Weather>>
とLoaderCallbacks<Cursor>
を1つのアクティビティにマージして、自分が望むように動作させる方法を想像できません。
は実は、私はCursorLoader
戻ってその結果にURIを構築するために Cursor cursor = new CursorLoader(this, WeatherEntry.CONTENT_URI, projection, null, null, null);
のようなものに List<String> cities = new ArrayList<>();
を変更したいです。
しかし、別のスレッドで別のスレッドとHTTPクエリ(!)でSQLクエリを作成する必要があります。私たちはネストされたスレッド/ローダ(SQLクエリの範囲内でhttpクエリを実行し、List<T>
を返す)を行うべきですか?たとえそれが可能なのか想像もできません...
私を助けてください、私は立ち往生しました!