我有以下代码,我想将Mysql与SQLITE同步。问题是当我点击同步按钮时出现错误。数据正在从Mysql服务器传输到我的SQLITE,但它不会出现在我将数据放入列表的应用程序的活动中。
public class MainActivity extends ActionBarActivity {
// DB Class to perform DB related operations
DBController controller = new DBController(this);
// Progress Dialog Object
ProgressDialog prgDialog;
HashMap<String, String> queryValues;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get User records from SQLite DB
ArrayList<HashMap<String, String>> userList = controller.getAllUsers();
// If users exists in SQLite DB
if (userList.size() != 0) {
// Set the User Array list in ListView
ListAdapter adapter = new SimpleAdapter(MainActivity.this, userList, R.layout.view_user_entry, new String[] {
"userId", "userName" }, new int[] { R.id.userId, R.id.userName });
ListView myList = (ListView) findViewById(android.R.id.list);
myList.setAdapter(adapter);
}
// Initialize Progress Dialog properties
prgDialog = new ProgressDialog(this);
prgDialog.setMessage("Transferring Data from Remote MySQL DB and Syncing SQLite. Please wait...");
prgDialog.setCancelable(false);
// BroadCase Receiver Intent Object
Intent alarmIntent = new Intent(getApplicationContext(), SampleBC.class);
// Pending Intent Object
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// Alarm Manager Object
AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
// Alarm Manager calls BroadCast for every Ten seconds (10 * 1000), BroadCase further calls service to check if new records are inserted in
// Remote MySQL DB
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, Calendar.getInstance().getTimeInMillis() + 5000, 10 * 1000, pendingIntent);
}
// Options Menu (ActionBar Menu)
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
// When Options Menu is selected
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here.
int id = item.getItemId();
// When Sync action button is clicked
if (id == R.id.refresh) {
// Transfer data from remote MySQL DB to SQLite on Android and perform Sync
syncSQLiteMySQLDB();
return true;
}
return super.onOptionsItemSelected(item);
}
// Method to Sync MySQL to SQLite DB
public void syncSQLiteMySQLDB() {
// Create AsycHttpClient object
AsyncHttpClient client = new AsyncHttpClient();
// Http Request Params Object
RequestParams params = new RequestParams();
// Show ProgressBar
prgDialog.show();
// Make Http call to getusers.php
client.post("http://download.grupsapte.ro/sinc/getusers.php", params, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(String response) {
// Hide ProgressBar
prgDialog.hide();
// Update SQLite DB with response sent by getusers.php
updateSQLite(response);
}
// When error occured
@Override
public void onFailure(int statusCode, Throwable error, String content) {
// TODO Auto-generated method stub
// Hide ProgressBar
prgDialog.hide();
if (statusCode == 404) {
Toast.makeText(getApplicationContext(), "Requested resource not found", Toast.LENGTH_LONG).show();
} else if (statusCode == 500) {
Toast.makeText(getApplicationContext(), "Something went wrong at server end", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Unexpected Error occcured! [Most common Error: Device might not be connected to Internet]",
Toast.LENGTH_LONG).show();
}
}
});
}
public void updateSQLite(String response){
ArrayList<HashMap<String, String>> usersynclist;
usersynclist = new ArrayList<HashMap<String, String>>();
// Create GSON object
Gson gson = new GsonBuilder().create();
try {
// Extract JSON array from the response
JSONArray arr = new JSONArray(response);
System.out.println(arr.length());
// If no of array elements is not zero
if(arr.length() != 0){
// Loop through each array element, get JSON object which has userid and username
for (int i = 0; i < arr.length(); i++) {
// Get JSON object
JSONObject obj = (JSONObject) arr.get(i);
System.out.println(obj.get("userId"));
System.out.println(obj.get("userName"));
// DB QueryValues Object to insert into SQLite
queryValues = new HashMap<String, String>();
// Add userID extracted from Object
queryValues.put("userId", obj.get("userId").toString());
// Add userName extracted from Object
queryValues.put("userName", obj.get("userName").toString());
// Insert User into SQLite DB
controller.insertUser(queryValues);
HashMap<String, String> map = new HashMap<String, String>();
// Add status for each User in Hashmap
map.put("Id", obj.get("userId").toString());
map.put("status", "1");
usersynclist.add(map);
}
// Inform Remote MySQL DB about the completion of Sync activity by passing Sync status of Users
updateMySQLSyncSts(gson.toJson(usersynclist));
// Reload the Main Activity
reloadActivity();
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Method to inform remote MySQL DB about completion of Sync activity
public void updateMySQLSyncSts(String json) {
System.out.println(json);
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
params.put("syncsts", json);
// Make Http call to updatesyncsts.php with JSON parameter which has Sync statuses of Users
client.post("http://download.grupsapte.ro/sinc/updatesyncsts.php", params, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(String response) {
Toast.makeText(getApplicationContext(), "MySQL DB has been informed about Sync activity", Toast.LENGTH_LONG).show();
}
@Override
public void onFailure(int statusCode, Throwable error, String content) {
Toast.makeText(getApplicationContext(), "Error Occured", Toast.LENGTH_LONG).show();
}
});
}
// Reload MainActivity
public void reloadActivity() {
Intent objIntent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(objIntent);
}
}
错误如下:
01-18 12:54:59.821: E/WindowManager(2022): android.view.WindowLeaked: Activity com.prgguru.example.MainActivity has leaked window com.android.internal.policy.PhoneWindow$DecorView{a19b187 G.E...... R.....ID 0,0-1336,384} that was originally added here
01-18 12:54:59.821: E/WindowManager(2022): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:565)
01-18 12:54:59.821: E/WindowManager(2022): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:326)
01-18 12:54:59.821: E/WindowManager(2022): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
01-18 12:54:59.821: E/WindowManager(2022): at android.app.Dialog.show(Dialog.java:350)
01-18 12:54:59.821: E/WindowManager(2022): at com.prgguru.example.MainActivity.syncSQLiteMySQLDB(MainActivity.java:96)
01-18 12:54:59.821: E/WindowManager(2022): at com.prgguru.example.MainActivity.onOptionsItemSelected(MainActivity.java:83)
01-18 12:54:59.821: E/WindowManager(2022): at android.app.Activity.onMenuItemSelected(Activity.java:3204)
01-18 12:54:59.821: E/WindowManager(2022): at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:353)
01-18 12:54:59.821: E/WindowManager(2022): at android.support.v7.app.ActionBarActivity.superOnMenuItemSelected(ActionBarActivity.java:244)
01-18 12:54:59.821: E/WindowManager(2022): at android.support.v7.app.ActionBarActivityDelegateICS.onMenuItemSelected(ActionBarActivityDelegateICS.java:165)
01-18 12:54:59.821: E/WindowManager(2022): at android.support.v7.app.ActionBarActivity.onMenuItemSelected(ActionBarActivity.java:130)
01-18 12:54:59.821: E/WindowManager(2022): at android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.onMenuItemSelected(ActionBarActivityDelegateICS.java:300)
01-18 12:54:59.821: E/WindowManager(2022): at com.android.internal.policy.PhoneWindow.onMenuItemSelected(PhoneWindow.java:1259)
01-18 12:54:59.821: E/WindowManager(2022): at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:801)
01-18 12:54:59.821: E/WindowManager(2022): at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:155)
01-18 12:54:59.821: E/WindowManager(2022): at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:954)
01-18 12:54:59.821: E/WindowManager(2022): at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:944)
01-18 12:54:59.821: E/WindowManager(2022): at android.widget.ActionMenuView.invokeItem(ActionMenuView.java:655)
01-18 12:54:59.821: E/WindowManager(2022): at com.android.internal.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:251)
01-18 12:54:59.821: E/WindowManager(2022): at android.view.View.performClick(View.java:5697)
01-18 12:54:59.821: E/WindowManager(2022): at android.widget.TextView.performClick(TextView.java:10826)
01-18 12:54:59.821: E/WindowManager(2022): at android.view.View$PerformClick.run(View.java:22526)
01-18 12:54:59.821: E/WindowManager(2022): at android.os.Handler.handleCallback(Handler.java:739)
01-18 12:54:59.821: E/WindowManager(2022): at android.os.Handler.dispatchMessage(Handler.java:95)
01-18 12:54:59.821: E/WindowManager(2022): at android.os.Looper.loop(Looper.java:158)
01-18 12:54:59.821: E/WindowManager(2022): at android.app.ActivityThread.main(ActivityThread.java:7225)
01-18 12:54:59.821: E/WindowManager(2022): at java.lang.reflect.Method.invoke(Native Method)
01-18 12:54:59.821: E/WindowManager(2022): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
01-18 12:54:59.821: E/WindowManager(2022): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
我知道我应该放一个this.finish(),但我不确切知道在哪里。希望有人帮助我。
答案 0 :(得分:1)
public void syncSQLiteMySQLDB() {
// Create AsycHttpClient object
AsyncHttpClient client = new AsyncHttpClient();
// Http Request Params Object
RequestParams params = new RequestParams();
// Show ProgressBar
prgDialog = new ProgressDialog(MainActivity.this);
prgDialog.setMessage("Transferring Data from Remote MySQL DB and Syncing SQLite. Please wait...");
prgDialog.setCancelable(false);
prgDialog.show();
// Make Http call to getusers.php
client.post("http://download.grupsapte.ro/sinc/getusers.php", params, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(String response) {
// Update SQLite DB with response sent by getusers.php
updateSQLite(response);
}
// When error occured
@Override
public void onFailure(int statusCode, Throwable error, String content) {
// TODO Auto-generated method stub
if (statusCode == 404) {
Toast.makeText(getApplicationContext(), "Requested resource not found", Toast.LENGTH_LONG).show();
} else if (statusCode == 500) {
Toast.makeText(getApplicationContext(), "Something went wrong at server end", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Unexpected Error occcured! [Most common Error: Device might not be connected to Internet]",
Toast.LENGTH_LONG).show();
}
}
@Override
public void onFinish(){
// Hide ProgressBar
if(prgDialog.isShowing())
prgDialog.hide();
}
});
}
首先,您应该声明本地进度条对象并使用MainActivity初始化。这也是AsyncHttpClient有一个方法onFinish()
,它将在调用成功或失败后调用,因此您只需要在onfinsh方法中隐藏进度条,你总是应该检查进度条是否显示,这样就不会导致产生异常
答案 1 :(得分:0)
尝试, 在显示进度对话框之前。检查它是否已经显示,如果是,则将其关闭并显示对话框。
在syncSQLiteMySQLDB中,您将显示进度对话框。首先检查您是否已经有一个prgDialog实例及其显示。然后关闭现有的prgDialog并显示。并在显示之前检查活动是否未完成。
public void syncSQLiteMySQLDB() {
....
if( !isFinishing()) {
if(prgDialog !=null) {
if(prgDialog.isShowing()) {
prgDialog.dismiss()
}
prgDialog.show();
}
}
}
答案 2 :(得分:0)
您需要dismiss
()progressDialog
@Override
public void onSuccess(String response) {
// dismiss ProgressBar
if (prgDialog != null) {
prgDialog.dismiss(); //not hide try dismiss the dialog
// Update SQLite DB with response sent by getusers.php
updateSQLite(response);
}
}
也在您的onFailure
方法dismiss
()dialog
答案 3 :(得分:0)
您正在重新加载活动而不关闭对话框,所以您应该首先解雇。
public void reloadActivity() {
// dissmiss dialog first then reload activity.
if(prgDialog.isShowing()) {
prgDialog.dismiss();
Intent objIntent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(objIntent);
}
}
答案 4 :(得分:0)
花了几分钟找到此内存泄漏,无需在准备对话框生成器中使用.show
@Override
protected void onPrepareDialogBuilder(final AlertDialog.Builder builder) {
builder
.setIcon(getIconImage(context))
.setTitle("title)
.setMessage("message")
.setPositiveButton("ok",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
start intent
}
})
.setNegativeButton("cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
})
.show();
}
else{
do something else
}
}