Android中如何用Parse Server查询更新应用?实时展示表内容到ListView求助
Hey there! Let's tackle your two requirements one by one—getting real-time data from your Parse Server table into an Android ListView, and implementing app updates using Parse queries. I'll walk you through practical, working code examples and best practices.
1. Displaying Parse Server Data in ListView (Real-time)
Step 1: Ensure Parse SDK is Properly Initialized
First, make sure you've set up the Parse SDK in your Android project. In your Application class or main activity's onCreate():
Parse.initialize(new Parse.Configuration.Builder(context) .applicationId("YOUR_APP_ID") .clientKey("YOUR_CLIENT_KEY") .server("YOUR_PARSE_SERVER_URL/parse/") .build()); // Initialize LiveQuery for real-time updates ParseLiveQueryClient parseLiveQueryClient = ParseLiveQueryClient.Factory.getClient();
Step 2: Create a Parse Data Model
Define a model class for your table (replace YourTableName with your actual table name):
@ParseClassName("YourTableName") public class YourDataModel extends ParseObject { // Define getter/setter for your columns public String getTitle() { return getString("title"); } public void setTitle(String title) { put("title", title); } // Add other fields as per your table }
Don't forget to register this model in your Application class:
ParseObject.registerSubclass(YourDataModel.class);
Step 3: Set Up ListView and Adapter
Use a ListAdapter (or a custom adapter for complex layouts) to bind data to your ListView. Let's use a basic ArrayAdapter for simplicity:
// In your Activity/Fragment private ListView listView; private ArrayAdapter<YourDataModel> adapter; private List<YourDataModel> dataList = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = findViewById(R.id.list_view); adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataList); listView.setAdapter(adapter); // Load initial data and set up real-time updates loadInitialData(); setupLiveQuery(); }
Step 4: Load Initial Data (One-time Query)
Fetch existing data from Parse Server asynchronously:
private void loadInitialData() { ParseQuery<YourDataModel> query = ParseQuery.getQuery(YourDataModel.class); query.findInBackground(new FindCallback<YourDataModel>() { @Override public void done(List<YourDataModel> objects, ParseException e) { if (e == null) { dataList.clear(); dataList.addAll(objects); adapter.notifyDataSetChanged(); } else { // Handle error Toast.makeText(MainActivity.this, "Failed to load data: " + e.getMessage(), Toast.LENGTH_SHORT).show(); } } }); }
Step 5: Implement Real-time Updates with LiveQuery
Subscribe to your Parse table to get real-time notifications when data is created, updated, or deleted:
private void setupLiveQuery() { ParseLiveQueryClient client = ParseLiveQueryClient.Factory.getClient(); ParseQuery<YourDataModel> query = ParseQuery.getQuery(YourDataModel.class); // Subscribe to the query SubscriptionHandling<YourDataModel> subscriptionHandling = client.subscribe(query); // Handle new objects added subscriptionHandling.handleEvent(SubscriptionHandling.Event.CREATE, (query1, object) -> { runOnUiThread(() -> { dataList.add(object); adapter.notifyDataSetChanged(); }); }); // Handle updated objects subscriptionHandling.handleEvent(SubscriptionHandling.Event.UPDATE, (query1, object) -> { runOnUiThread(() -> { int index = findIndexById(object.getObjectId()); if (index != -1) { dataList.set(index, object); adapter.notifyDataSetChanged(); } }); }); // Handle deleted objects subscriptionHandling.handleEvent(SubscriptionHandling.Event.DELETE, (query1, object) -> { runOnUiThread(() -> { int index = findIndexById(object.getObjectId()); if (index != -1) { dataList.remove(index); adapter.notifyDataSetChanged(); } }); }); } // Helper method to find index of an object by its ObjectId private int findIndexById(String objectId) { for (int i = 0; i < dataList.size(); i++) { if (dataList.get(i).getObjectId().equals(objectId)) { return i; } } return -1; }
2. Implement App Updates via Parse Queries
Step 1: Create an "AppUpdate" Table in Parse Server
First, create a new table in your Parse dashboard with these fields:
latestVersionCode(Number, int): The version code of the latest app versionlatestVersionName(String): The version name (e.g., "1.1.0")updateUrl(String): Download link for the APK (or Play Store URL)isMandatory(Boolean): Whether the update is required
Step 2: Check for Updates on App Launch
Add this logic to your splash screen or main activity's onCreate():
private void checkForAppUpdate() { ParseQuery<ParseObject> query = ParseQuery.getQuery("AppUpdate"); query.orderByDescending("createdAt"); // Get the latest update record query.setLimit(1); query.getFirstInBackground(new GetCallback<ParseObject>() { @Override public void done(ParseObject updateObject, ParseException e) { if (e == null && updateObject != null) { int latestVersionCode = updateObject.getInt("latestVersionCode"); String updateUrl = updateObject.getString("updateUrl"); boolean isMandatory = updateObject.getBoolean("isMandatory"); // Get current app version code int currentVersionCode = getCurrentVersionCode(); if (latestVersionCode > currentVersionCode) { // Show update dialog showUpdateDialog(updateUrl, isMandatory); } } else { // Handle error or no update found } } }); } // Helper to get current app version code private int getCurrentVersionCode() { try { PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0); return Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? (int) packageInfo.getLongVersionCode() : packageInfo.versionCode; } catch (PackageManager.NameNotFoundException e) { e.printStackTrace(); return 0; } } // Show update prompt dialog private void showUpdateDialog(String updateUrl, boolean isMandatory) { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("New Update Available") .setMessage("A newer version of the app is ready. Please update to continue.") .setPositiveButton("Update", (dialog, which) -> { // Open update URL Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(updateUrl)); startActivity(intent); }); if (!isMandatory) { builder.setNegativeButton("Later", (dialog, which) -> dialog.dismiss()); } AlertDialog dialog = builder.create(); dialog.setCancelable(!isMandatory); // Prevent closing if mandatory dialog.show(); }
Pro Tips
- Permissions: Don't forget to add
INTERNETpermission in yourAndroidManifest.xml:<uses-permission android:name="android.permission.INTERNET" /> - Background Threads: All Parse queries are asynchronous by default, so you don't have to worry about blocking the main thread—but always update UI elements on the main thread (we used
runOnUiThread()in the LiveQuery handlers for this). - LiveQuery Connection: Make sure your Parse Server has LiveQuery enabled (check your server configuration for
liveQuerysettings).
内容的提问来源于stack exchange,提问作者Gunjan Mehta

