Ich bin ziemlich neu in einer Android-Entwicklung und versuche derzeit, eine App zu schreiben, die das Wetter von morgen von mehreren Städten zeigen wird. Entschuldigung für alle fehlerhaften Begriffe, die ich in dieser Frage verwenden könnte.Android. Daten aus der Datenbank abrufen und dann eine Netzwerkabfrage durchführen. Wie zu implementieren?
Was ich erreichen möchte:
App werden die Daten von der lokalen Datenbank holen, dann eine HTTP-Abfrage auf die von einer DB abgerufenen Daten bauen, JSON-Antwort zu erhalten und eine Liste Elemente bilden.
Was ich derzeit haben:
Alles außer SQL-Funktionalität.
Hier ist der Schnappschuss meines Hauptaktivitätscodes. Ich benutze LoaderCallbacks<List<Weather>>
, um URI mit den erforderlichen Parametern in zu bauen, senden HTTP-Abfrage und erhalten die Daten über WeatherLoader(this, uriList)
, und Formularelemente Ergebnisse in List
mit 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();
}
Wie Sie sehen, Städte sind "Hardcoded" über List<String> cities = new ArrayList<>();
in onCreateLoader(int i, Bundle bundle)
. Aus diesem Grund habe ich beschlossen, den SQL-Speicher von Städten in meiner App zu implementieren. Ich weiß, wie man SQL-Funktionalität in Android-App mit ContentProvider
und CursorAdapter
implementieren.
Also, was ist das Problem?
Wenn ich richtig bin, sollten wir LoaderManager.LoaderCallbacks<Cursor>
verwenden, wenn wir eine Abfrage an eine lokale DB vornehmen möchten.
Leider kann ich mir nicht vorstellen, wie LoaderCallbacks<List<Weather>>
und LoaderCallbacks<Cursor>
in einer Aktivität zusammengeführt werden, damit es funktioniert, wie ich will.
Eigentlich möchte ich List<String> cities = new ArrayList<>();
auf etwas ändern, wie Cursor cursor = new CursorLoader(this, WeatherEntry.CONTENT_URI, projection, null, null, null);
die URI auf die Ergebnisse, dass CursorLoader
kehrt zu bauen.
Aber wir sollten SQL-Abfrage in separaten Thread und HTTP-Abfrage auch (!) In separaten Thread. Sollten wir verschachtelte Threads/Loader (http-Abfrage in einem Bereich von sql Abruf von Daten und Rückgabe eines List<T>
)? Kann mir gar nicht vorstellen, wie es geht, wenn ja ...
Hilf mir bitte, ich habe fest!