I am very new to android and would really appreciate the feedback.
My program executes a basic local database transaction through an async task. The task is passed the object (who's info will be stored) and a Interface which triggered once the db operation is complete.
Util - General class containing createProgressDialog code:
public class General {
public static boolean hasNetworkConnection(Context c){
ConnectivityManager connectivityManager = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
return (info != null && info.isConnected());
}
public static ProgressDialog createProgressDialog(Context c, String message){
ProgressDialog progressDialog = new ProgressDialog(c, R.style.AppTheme_Dark_Dialog);
progressDialog.setIndeterminate(true);
progressDialog.setMessage(message);
progressDialog.show();
return progressDialog;
}
public static void createDatePicker(FragmentActivity activity, DatePicker.DatePickerInterface callback){
DatePicker d = DatePicker.newInstance(callback);
d.show(activity.getSupportFragmentManager(), "DATE_PICKER");
}
}
Async class:
public class RetrieveStudentInfo extends AsyncTask<Void, Void, Void>{
private ServerDatabaseHelper serverDatabaseHelper;
private LocalDatabaseHelper localDatabaseHelper;
private Context context;
private long userId;
private MainCallback callback;
private ProgressDialog progressDialog;
private String message;
public RetrieveStudentInfo(ServerDatabaseHelper serverDatabaseHelper, LocalDatabaseHelper localDatabaseHelper, Context c, long userId, MainCallback callback, String message){
this.serverDatabaseHelper = serverDatabaseHelper;
this.localDatabaseHelper = localDatabaseHelper;
context = c;
this.userId = userId;
this.callback = callback;
this.message = message;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
//progressDialog = General.createProgressDialog(context, message);
}
@Override
protected Void doInBackground(Void... params) {
/*if(General.hasNetworkConnection(context))
else*/
// TODO: test - Will only be loading from local (Rest of the program will make sure it's synced up to date)
localDatabaseHelper.retrieveStudentInfo(userId, callback);
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
//progressDialog.dismiss();
}
}
The main class:
public class MainActivity extends AppCompatActivity implements MainCallback{
private static final int REQUEST_LOGIN = 0;
private DatabaseManager databaseManager;
private SharedPreferenceManager sharedPreferenceManager;
private Student loggedInStudent;
private TextView tempText; // TODO: take this out
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
tempText = (TextView) findViewById(R.id.tempText);
databaseManager = DatabaseManager.getInstance(this);
sharedPreferenceManager = SharedPreferenceManager.getInstance(this);
Intent intent = new Intent(this, LoginSignUpActivityActivity.class);
startActivityForResult(intent, REQUEST_LOGIN);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_update_info) {
Intent intent = new Intent(this, LoginSignUpActivityActivity.class);
intent.putExtra(LoginSignUpActivityActivity.KEY_STUDENT_INFO_TO_UPDATE, loggedInStudent);
startActivityForResult(intent, REQUEST_LOGIN);
return true;
}
if (id == R.id.action_logout) {
Intent intent = new Intent(this, LoginSignUpActivityActivity.class);
startActivityForResult(intent, REQUEST_LOGIN);
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == REQUEST_LOGIN){
if(resultCode == RESULT_OK){
long userId = data.getExtras().getLong(LoginSignUpActivityActivity.KEY_USER_ID);
Log.d("Test","Logged in, start main activity's sql controller");
Log.d("Test",Long.toString(userId));
// TODO: something - get student info to be displayed as default for now
databaseManager.retrieveStudentInfo(userId, this, "Retrieving info...");
}
}
}
@Override
public void retrieveStudentInfoFeedback(final Student s) {
new Thread()
{
public void run()
{
runOnUiThread(new Runnable()
{
public void run()
{
//Do your UI operations like dialog opening or Toast here
if(s != null){
MainActivity.this.loggedInStudent = s;
Log.d("Test", "Woo: " + s.getPerson().getName());
tempText.setText("Welcome: " + " " + s.getPerson().getName());
Toast.makeText(MainActivity.this, "Welcome " + s.getPerson().getName(), Toast.LENGTH_SHORT).show();
}
else{
// TODO: error loading info- do something
}
}
});
}
}.start();
}
}
The program returns the expected data just fine I can display the data in a textView or toast info about it without any errors However if i try to send the object retrieved to an intent, the program responds with this error:
01-05 12:26:44.027 2299-
3150/studentregistration5.test.co.za.studentregistration5
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #6
Process: studentregistration5.test.co.za.studentregistration5, PID:
2299
java.lang.RuntimeException: An error occurred while executing
doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:325)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor
.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker
.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method
'void
studentregistration5.test.co.za.studentregistration5
.localPOJO.Person
.setUser(studentregistration5.test.co.za.
studentregistration5.localPOJO.User)' on a null object reference
at studentregistration5.test.co.za.
studentregistration5.localTransactionTracker
.StudentTracker.get(StudentTracker.java:63)
at studentregistration5.test.co.za
.studentregistration5.databaseHelper
.LocalDatabaseHelper.retrieveStudentInfo(LocalDatabaseHelper.java:87)
at studentregistration5.test.co.za
.studentregistration5.asyncTransactionTask
.RetrieveStudentInfo.doInBackground(RetrieveStudentInfo.java:50)
at studentregistration5.test.co.za
.studentregistration5.asyncTransactionTask
.RetrieveStudentInfo.doInBackground(RetrieveStudentInfo.java:16)
at android.os.AsyncTask$2.call(AsyncTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
at java.util.concurrent.ThreadPoolExecutor
.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent
.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
01-05 12:26:45.155 2299-
2299/studentregistration5.test.co.za.studentregistration5
E/WindowManager: android.view.WindowLeaked: Activity
studentregistration5.test.co.za.studentregistration5.MainActivity
has leaked window DecorView@ab64a80[] that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:418)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at android.app.Dialog.show(Dialog.java:322)
at studentregistration5.test.co.za
.studentregistration5.util.General.createProgressDialog(General.java:28)
at studentregistration5.test.co.za
.studentregistration5.asyncTransactionTask
.RetrieveStudentInfo.onPreExecute(RetrieveStudentInfo.java:42)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:620)
at android.os.AsyncTask.execute(AsyncTask.java:567)
at studentregistration5.test.co.za
.studentregistration5.manager.DatabaseManager
.retrieveStudentInfo(DatabaseManager.java:55)
at studentregistration5.test.co.za
.studentregistration5.MainActivity.onActivityResult(MainActivity.java:78)
at android.app.Activity.dispatchActivityResult(Activity.java:6932)
at android.app.ActivityThread.deliverResults(ActivityThread.java:4085)
at android.app.ActivityThread.handleSendResult(ActivityThread.java:4132)
at android.app.ActivityThread.-wrap20(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1533)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os
.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
The issue occurs when I am tap the menu and click on the update user info item
Appreciate the help