I know this has been posted multiple times now, but nothing seemed to fix my problem. I create a Loading Dialog on the UI thread, then start another thread which is doing some networking stuff and via interface, the class gets a callback, when networking is done. The problem is, after its done, i cant remove the loading dialog, even with "runOnUIThread". Here is the code:
public void onClickLoginButton (View view) {
if (!((EditText)findViewById(R.id.textNickname)).getText().toString().isEmpty() &&
!((EditText)findViewById(R.id.textPassword)).getText().toString().isEmpty()) {
loggingIn = new ProgressDialog(this);
loggingIn.setTitle("Login");
loggingIn.setMessage("Wait while logging in...");
loggingIn.show();
final LoginInterface callbackInterface = this;
new Thread(new Runnable() {
public void run() {
Networking net = new Networking();
net.Login(((EditText) findViewById(R.id.textNickname)).getText().toString(), ((EditText) findViewById(R.id.textPassword)).getText().toString(), callbackInterface);
}
}).start();
}
}
And this is the function that gets called by the networking stuff, after its done:
#Override
public void LoginCallback(final boolean loginSuccess, final boolean isActivated) {
loggingIn.hide();
loggingIn = null;
final Context context = this;
runOnUiThread(new Runnable() {
#Override
public void run() {
if (loginSuccess && isActivated) {
loggingIn.hide();
loggingIn = null;
finish();
} else if (loginSuccess == false) {
Toast.makeText(context, "Login failed! User/Password wrong", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Login failed! Account not activated", Toast.LENGTH_SHORT).show();
}
}
});
}
And this is the stack trace:
04-17 17:06:11.313 13018-13121/com.assigame.nidhoegger.assigame E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-1422
Process: com.assigame.nidhoegger.assigame, PID: 13018
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6122)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:850)
at android.view.View.requestLayout(View.java:16431)
at android.view.View.setFlags(View.java:8908)
at android.view.View.setVisibility(View.java:6036)
at android.app.Dialog.hide(Dialog.java:299)
at com.assigame.nidhoegger.assigame.Login.LoginCallback(Login.java:72)
at com.assigame.nidhoegger.assigame.Networking.Login(Networking.java:134)
at com.assigame.nidhoegger.assigame.Login$1.run(Login.java:64)
at java.lang.Thread.run(Thread.java:841)
04-17 17:06:11.719 13018-13018/com.assigame.nidhoegger.assigame E/WindowManager﹕ android.view.WindowLeaked: Activity com.assigame.nidhoegger.assigame.Login has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{42284588 G.E..... R......D 0,0-684,324} that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:366)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
at android.app.Dialog.show(Dialog.java:286)
at com.assigame.nidhoegger.assigame.Login.onClickLoginButton(Login.java:56)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at android.view.View$1.onClick(View.java:3818)
at android.view.View.performClick(View.java:4438)
at android.view.View$PerformClick.run(View.java:18422)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
You are calling the loggingIn.hide() method twice, and the first time not on the UI thread. Change your code to this:
#Override
public void LoginCallback(final boolean loginSuccess, final boolean isActivated) {
final Context context = this;
runOnUiThread(new Runnable() {
#Override
public void run() {
if (loginSuccess && isActivated) {
loggingIn.hide();
loggingIn = null;
finish();
} else if (loginSuccess == false) {
Toast.makeText(context, "Login failed! User/Password wrong", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Login failed! Account not activated", Toast.LENGTH_SHORT).show();
}
}
});
}
Related
I have a activity and a login button. When I clicked the login Button then a progress bar will load for 10 seconds and after that the fragment will load. But I am getting an error.
Here is my code:
handler=new Handler();
runnable=new Runnable() {
#Override
public void run() {
if (loader_fragment != null) {
AVLoadingIndicatorView loader = loader_fragment.getView().findViewById(R.id.loder_login);
loader.setVisibility(View.INVISIBLE);
timer.cancel();
}
Home_Screen home_screen = (Home_Screen) getFragmentManager()
.findFragmentById(R.id.Home_screen_fragment);
fragmentManager1 = getFragmentManager();
fragmentTransaction1 = fragmentManager1.beginTransaction();
fragmentTransaction1.setCustomAnimations(R.animator
.slide_in_left, R.animator.slide_out_left, R.animator
.slide_in_right, R.animator.slide_out_right);
//Home_screen_student home_screen_student = new
//Home_screen_student();
fragmentTransaction1.replace(R.id.Home_screen_fragment,
new Home_Screen());
fragmentTransaction1.addToBackStack(null);
fragmentTransaction1.commit();
}
};
timer=new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
handler.post(runnable);
}
}, 10000,1000);
}
Logcat:
04-24 02:01:07.437 12567-12567/? E/Zygote: no v2
04-24 02:03:09.912 12567-12567/com.example.user.attendance E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.user.attendance, PID: 12567
java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1433)
at android.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1451)
at android.app.BackStackRecord.commitInternal(BackStackRecord.java:687)
at android.app.BackStackRecord.commit(BackStackRecord.java:663)
at com.example.user.attendance.MainActivity$3$2.run(MainActivity.java:186)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7402)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
The fragment keep opening from left to right like a loop until the app stopped.
Logcat error message.
I receive this error when I attempt to register an account on the application, the app crashes momentarily and returns to the login page.
02-14 13:11:19.857 31983-31983/example.com.androidim E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: example.com.androidim, PID: 31983
java.lang.NullPointerException
at example.com.androidim.SignUp$2$1$1.run(SignUp.java:126)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:606
at dalvik.system.NativeStart.main(Native Method)
The following is line 111-142 in the SignUp activity.
if (passwordText.getText().toString().equals(passwordAgainText.getText().toString())){
if (usernameText.length() >= 5 && passwordText.length() >= 5) {
Thread thread = new Thread(){
String result = new String();
#Override
public void run() {
result = imService.signUpUser(usernameText.getText().toString(),
passwordText.getText().toString(),
eMailText.getText().toString());
handler.post(new Runnable(){
public void run() {
if (result.equals(SERVER_RES_RES_SIGN_UP_SUCCESFULL)) {
Toast.makeText(getApplicationContext(),R.string.signup_successfull, Toast.LENGTH_LONG).show();
showDialog(SIGN_UP_SUCCESSFULL);
}
else if (result.equals(SERVER_RES_SIGN_UP_USERNAME_CRASHED)){
Toast.makeText(getApplicationContext(),R.string.signup_username_crashed, Toast.LENGTH_LONG).show();
showDialog(SIGN_UP_USERNAME_CRASHED);
}
else //if (result.equals(SERVER_RES_SIGN_UP_FAILED))
{
Toast.makeText(getApplicationContext(),R.string.signup_failed, Toast.LENGTH_LONG).show();
showDialog(SIGN_UP_FAILED);
}
}
});
}
When calling equals on your result variable, result is null. You have to do a null-check before calling equals.
public void run() {
if(result != null){
if (result.equals(SERVER_RES_RES_SIGN_UP_SUCCESFULL)) {
Toast.makeText(getApplicationContext(),R.string.signup_successfull, Toast.LENGTH_LONG).show();
showDialog(SIGN_UP_SUCCESSFULL);
}
else if (result.equals(SERVER_RES_SIGN_UP_USERNAME_CRASHED)){
Toast.makeText(getApplicationContext(),R.string.signup_username_crashed, Toast.LENGTH_LONG).show();
showDialog(SIGN_UP_USERNAME_CRASHED);
}
else //if (result.equals(SERVER_RES_SIGN_UP_FAILED))
{
Toast.makeText(getApplicationContext(),R.string.signup_failed, Toast.LENGTH_LONG).show();
showDialog(SIGN_UP_FAILED);
}else{
//result == null
}
}
}
I'm trying to implement a system service on Android with inter-process communication based on binding a messenger. For this I'm following this tutorial:
http://www.survivingwithandroid.com/2014/01/android-bound-service-ipc-with-messenger.html
But no matter what I'm trying, i can't get it to work.
I found different tutorials online but in the end they are all based on the same procedure.
The app will crash right away when I'm trying to communicate with the service.
Error message
10-09 15:40:33.490 3468-3468/com.example.stenosis.testservice E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.stenosis.testservice, PID: 3468
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.stenosis.testservice/com.example.stenosis.testservice.MyActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2184)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.example.stenosis.testservice.MyActivity.sendMsg(MyActivity.java:87)
at com.example.stenosis.testservice.MyActivity.onCreate(MyActivity.java:49)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2148)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2233)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
MyActivity.java:
public class MyActivity extends Activity {
private ServiceConnection sConn;
private Messenger messenger;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
// Service Connection to handle system callbacks
sConn = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
messenger = null;
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
// We are conntected to the service
messenger = new Messenger(service);
}
};
// We bind to the service
bindService(new Intent(this, MyService.class), sConn, Context.BIND_AUTO_CREATE);
// Try to send a message to the service
sendMsg();
}
// This class handles the Service response
class ResponseHandler extends Handler {
#Override
public void handleMessage(Message msg) {
int respCode = msg.what;
String result = "";
switch (respCode) {
case MyService.TO_UPPER_CASE_RESPONSE: {
result = msg.getData().getString("respData");
System.out.println("result");
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
}
}
}
}
public void sendMsg() {
String val = "This is a test";
Message msg = Message
.obtain(null, MyService.TO_UPPER_CASE);
msg.replyTo = new Messenger(new ResponseHandler());
// We pass the value
Bundle b = new Bundle();
b.putString("data", val);
msg.setData(b);
try {
messenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
MyService.java
public class MyService extends Service {
public static final int TO_UPPER_CASE = 0;
public static final int TO_UPPER_CASE_RESPONSE = 1;
private Messenger msg = new Messenger(new ConvertHanlder());;
#Override
public IBinder onBind(Intent intent) {
return msg.getBinder();
}
class ConvertHanlder extends Handler {
#Override
public void handleMessage(Message msg) {
// This is the action
int msgType = msg.what;
switch (msgType) {
case TO_UPPER_CASE: {
try {
// Incoming data
String data = msg.getData().getString("data");
Message resp = Message.obtain(null, TO_UPPER_CASE_RESPONSE);
Bundle bResp = new Bundle();
bResp.putString("respData", data.toUpperCase());
resp.setData(bResp);
msg.replyTo.send(resp);
} catch (RemoteException e) {
e.printStackTrace();
}
break;
}
default:
super.handleMessage(msg);
}
}
}
}
AndroidManifest.xml
<service android:name=".MyService" android:process=":convertprc"/>
Your problem is that the messanger property is null. You are experiencing concurrency problem. The bindService method is asynchronous - it returns immediately and performs the binding in a background thread. When the binding is done, the onServiceConnected method is invoked. When you try to send the message, the messanger is still not initialized because the onServiceConnected method is hasn't been executed yet.
I have an async Task that repeats itself, until a statement is true. Therefore I use this code(simplified):
public class AnalyzingTask extends AsyncTask<String, JSONObject, Void>
{
private final ReentrantLock lock = new ReentrantLock();
private final Condition tryAgain = lock.newCondition();
private volatile boolean finished = false;
#Override
protected Void doInBackground(String... params)
{
try
{
lock.lockInterruptibly();
do {
...somecode...
publishProgress(result)
tryAgain.await();
}
while (!finished);
lock.unlock();
}
catch(Exception e){
publishProgress(null);
}
return null;
}
#Override
protected void onProgressUpdate(JSONObject... result)
{
..someCode...
if(state.equals("Available"))
{
terminateTask();
}
else
{
runAgain();
}
}
public void runAgain() {
// Call this to request data from the server again
tryAgain.signal();
}
public void terminateTask() {
// The task will only finish when we call this method
finished = true;
if(lock.isLocked())
{
lock.unlock();
}
}
#Override
protected void onCancelled() {
// Make sure we clean up if the task is killed
terminateTask();
}
#Override
protected void onPostExecute(Void result)
{
return;
}
}
I debugged this code, and terminateTask() gets called normal, after "state" has the right value.
Nevertheless, onPostExecuted never gets called. It wouldn't be a problem, but I cant start another Task, as long as this one is running.
Why is this Task not finishing as normal?
Stacktrace when adding signal() as asked in the comments:
8008-8008/com.michi.undroid E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.michi.undroid, PID: 8008
java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signal(AbstractQueuedSynchronizer.java:1917)
at com.michi.undroid.AnalyzingTask.terminateTask(AnalyzingTask.java:166)
at com.michi.undroid.AnalyzingTask$1.run(AnalyzingTask.java:127)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy#406a6678 is not valid; is your activity running?
at android.view.ViewRoot.setView(ViewRoot.java:528)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
at android.view.Window$LocalWindowManager.addView(Window.java:424)
at android.app.Dialog.show(Dialog.java:241)
at android.app.Activity.showDialog(Activity.java:2569)
at android.app.Activity.showDialog(Activity.java:2527)
at MyCode$8$4.run(MyCode.java:557)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3683)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)
at dalvik.system.NativeStart.main(Native Method)
I am getting above exception when following code is executed. This file dialog will shown once the processing is done and progressbar reaches 100%. FileSaveDialog extends Dialog and implements OnCompletionListener
runOnUiThread(new Runnable() {
#Override
public void run() {
showDialog(error.Code());//Line 557
}
});
#Override
protected Dialog onCreateDialog(int id) {
Dialog dialog;
AlertDialog.Builder builder;
final ScrollView scrollView = new ScrollView(this);
final TextView textView = new TextView(this);
switch (id) {
// Other cases are here
case 4:
File playFile = new File(mediaPath, TEMP_WAV_FILE_NAME);
dialog = new FileSaveDialog(this, getResources(),
playFile.getAbsolutePath(), saveDiscardHandler);
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
// do whatever you want the back key to do
cleanUp();
}
});
break;
// Other cases are here
default:
dialog = null;
}
return dialog;
}
You must check activity isFinishing() If the activity is finishing, returns true; else returns false.