Reputation: 5
The app I am working on has a login/register which connects to a mysql database, At first I was running everything on the UI Thread
I later found out it was not working because of the against running long code on Android's UI Thread
. I attempted to edit my code to run the long task on a new Thread
that i added.
. Now my app registers the I see the result in mysql but my app keeps closing because of this error
android.view.ViewRootImpl$CalledFromWrongThreadException:
Only the original thread that created a view hierarchy can touch its views.
the error is understandable but I don't know how to run the View
or View
s back to the UI Thread
.
I've done some research about the runOnuithread
but I dont know where to place it in my code, or weather I placed the new Thread
I added before in the wrong place to begin with please
can anyone help my fix this
here is a snippet of the code
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.register);
// Importing all assets like buttons, text fields
inputFullName = (EditText) findViewById(R.id.registerName);
inputEmail = (EditText) findViewById(R.id.registerEmail);
inputPassword = (EditText) findViewById(R.id.registerPassword);
btnRegister = (Button) findViewById(R.id.btnRegister);
btnLinkToLogin = (Button) findViewById(R.id.btnLinkToLoginScreen);
registerErrorMsg = (TextView) findViewById(R.id.register_error);
// Register Button Click event
btnRegister.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
/** According with the new StrictGuard policy, running long tasks on the Main UI thread is not possible
So creating new thread to create and execute http operations */
new Thread (new Runnable() {
@Override
public void run() {
//
String name = inputFullName.getText().toString();
String email = inputEmail.getText().toString();
String password = inputPassword.getText().toString();
UserFunctions userFunction = new UserFunctions();
JSONObject json = userFunction.registerUser(name, email, password);
// check for login response
try {
//
//
if (json.getString(KEY_SUCCESS) != null) {
registerErrorMsg.setText("");
String res = json.getString(KEY_SUCCESS);
if(Integer.parseInt(res) == 1){
// user successfully registred
// Store user details in SQLite Database
DatabaseHandler db = new DatabaseHandler(getApplicationContext());
JSONObject json_user = json.getJSONObject("user");
// Clear all previous data in database
userFunction.logoutUser(getApplicationContext());
db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT));
// Launch Dashboard Screen
Intent dashboard = new Intent(getApplicationContext(), MainActivity.class);
// Close all views before launching Dashboard
dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(dashboard);
// Close Registration Screen
finish();
}else{
// Error in registration
registerErrorMsg.setText("Error occured in registration");
}
}//
} catch (JSONException e) {
e.printStackTrace();
}
}
}).start();
}
});
// Link to Login Screen
btnLinkToLogin.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent i = new Intent(getApplicationContext(),
LoginActivity.class);
startActivity(i);
// Close Registration View
finish();
}
});
}
}
Upvotes: 0
Views: 633
Reputation: 44571
Since you seem to have network code mixed in with UI
code, I'm not going to try and write it for you. I can tell you how it should be and assume that you can rearrange the code yourself since you know what all of it does.
Ok, inside your run()
you put your network code then when you need to update the UI
you can have
runOnUiThread(new Runnable()
{
@Override
public void run()
{
// code to update UI
}
});
With that said, I recommend using AsyncTask for your network operations. This makes it much easier as it already has the functions for background stuff and updating the UI
. You start the task and doInBackground()
runs and that is where you do all of your network operations. Then you can update the UI
in any of AsyncTasks
other 3 methods.
See this answer for an example of using AsyncTask
, along with the link to the docs above.
Upvotes: 1