0

I have a bit of usual problem here. I have a alertdialog that launches as soon as my application has been launched and as soon as the user clicks the ok button that dialog will never display again unless it has been deleted and installed again. It works when I try it on my emulator for the first time and by first time I mean when I launch the application as soon I am done writing the code for the shared preference for the alertdialog. But when I close the emulator and launch my application again, the alertdialog doesn't display and my application doesn't respond to anything. I do not know if this happened to anybody before and I do not know if this was suppose to happen. Can somebody help me understand what is going and why application doesn't respond to anything after the first time the application has been launched. Also my logcat did not display any errors either.

public class MainActivity extends Activity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);



        final SharedPreferences settings = getSharedPreferences("pref_name", 0);
        boolean installed = settings.getBoolean("installed", false);

        if(!installed){

            final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);

            alertDialog.setTitle("Title");
            alertDialog.setIcon(R.drawable.ic_launcher);
            alertDialog.setAdapter(new MyAdapter(), null);

            alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int which) {
                    SharedPreferences.Editor editor = settings.edit();
                    editor.putBoolean("installed", true);
                    editor.commit();

                }
            });

            alertDialog.show();

            final EditText et = (EditText) findViewById(R.id.editText1);
            Button getAnswer = (Button) findViewById(R.id.button1);
            getAnswer.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {       
                    if (et.getText().toString().length()==0) {
                        Toast.makeText(getApplicationContext(),"Can't Be Blank!",Toast.LENGTH_LONG).show();             

                    }else{
                        EditText et = (EditText) findViewById(R.id.editText1);
                        String searchTerm = et.getText().toString().trim();         
                        Intent in = new Intent(MainActivity.this, ListView.class);
                        in.putExtra("TAG_SEARCH", searchTerm);
                        startActivity(in);
                    }

                }
            });
        }
     }


    @Override
    protected void onStop() {
        // TODO Auto-generated method stub
        super.onStop();
    }}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Inman Douche
  • 139
  • 3
  • 8

3 Answers3

1

You need to move this code

 final EditText et = (EditText) findViewById(R.id.editText1);
        Button getAnswer = (Button) findViewById(R.id.button1);
        getAnswer.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {       
                if (et.getText().toString().length()==0) {
                    Toast.makeText(getApplicationContext(),"Can't Be Blank!",Toast.LENGTH_LONG).show();             

                }else{
                    EditText et = (EditText) findViewById(R.id.editText1);
                    String searchTerm = et.getText().toString().trim();         
                    Intent in = new Intent(MainActivity.this, ListView.class);
                    in.putExtra("TAG_SEARCH", searchTerm);
                    startActivity(in);
                }

            }
        });
    }

out of the if part of your code. As Shobhit is saying, this is never getting run the next time you run your app. It only runs if installed is false which is never true after the first run.

Edit-Avoid window leak errors with the Dialog

You can always check if the Dialog is open with dialog.isShowing() and close the Dialog if returns true before the Activity is destroyed or something (another Activity) comes on top. You can do this in onPause().

@Override
public void onPause()
{
    if (dialog != null && dialog.isShowing())
    {    
         dialog.dismiss();    
         super.onPause();
    }
}
codeMagic
  • 44,549
  • 13
  • 77
  • 93
  • are you talking about the `if(!installed){` or the `if` that has my `editText`? – Inman Douche Sep 16 '13 at 23:13
  • `AsyncTask` is for "heavy-lifting" such as network operations or maybe very long calculations. Something like this is fine in `onCreate()` – codeMagic Sep 16 '13 at 23:15
  • ok, would it effect anything if `installed` is telling that it is not being used? – Inman Douche Sep 17 '13 at 00:48
  • No, that's just a warning but if it isn't being used then you don't need it – codeMagic Sep 17 '13 at 00:49
  • Wait, where is it decaled/initialized? If you have the same code then you shouldn't get that – codeMagic Sep 17 '13 at 00:50
  • sorry for the late response but yes I have the same and everything works fine although it still says `installed` is not being used – Inman Douche Sep 17 '13 at 22:35
  • Where does it say that? It will only be recognized in `onCreate()` since that's where its declared. If you have another `installed` somewhere then that one won't be used. Also, try cleaning your project – codeMagic Sep 17 '13 at 22:38
  • Underneath `installed` is says "The value of the local variable `installed` is not being used" – Inman Douche Sep 17 '13 at 22:41
  • the only thing I did to my code is get rid of `if(!installed){` – Inman Douche Sep 17 '13 at 22:42
  • Well then yes, it isn't being used anymore. I thought you kept that but removed the above code outside of the `if`. If you aren't using it at all anymore then you can just remove it. Either way, the warning won't hurt you – codeMagic Sep 17 '13 at 22:44
  • I just look like it working check logcat when you rotate the device. – Erik Sep 18 '13 at 06:36
  • your right I could not get this working but this is the easy way good you cleared this out – Erik Sep 18 '13 at 14:53
  • 1
    @Erik I assume you are talking about closing the `Dialog` in `onPause()`? If so maybe I will edit the answer for others to see easily – codeMagic Sep 18 '13 at 14:55
0

Move this code into an AsyncTask. It's not good practice to do any work in the onCreate(). The OnCreate() is only for creating the Activity. Start your AsyncTask in the OnResume() Look at this activity-life-cycle Here is the AsyncTask

 final SharedPreferences settings = getSharedPreferences("pref_name", 0);
 boolean installed = settings.getBoolean("installed", false);

if(!installed){

final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);

alertDialog.setTitle("Title");
alertDialog.setIcon(R.drawable.ic_launcher);
alertDialog.setAdapter(new MyAdapter(), null);

alertDialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {

    public void onClick(DialogInterface dialog, int which) {
           SharedPreferences.Editor editor = settings.edit();
           editor.putBoolean("installed", true);
           editor.commit();

    }
 });

alertDialog.show();
Community
  • 1
  • 1
Erik
  • 5,039
  • 10
  • 63
  • 119
  • `You cannot do any work in the onCreate()` Where is that mentioned int the documentation ? – Shobhit Puri Sep 13 '13 at 23:34
  • I changed my Answer to It's not good practice to do any work in the onCreate(). But i'm still right about my answer, live with it for the sake of the Android lifecykle :) – Erik Sep 13 '13 at 23:38
  • Sure Eric. I respect your views. I am just curious to know the source from where you've learned it as I want to learn why it is so. As far as I know the computation intensive tasks are made for `AsyncTask`, which would otherwise hang the UI thread. Those intensive tasks should be done in background, so that application doesn't have to wait on UI thread. In any case the `AlertDialog` operation that you mentioned in the answer cannot be done in Background thread( i.e `doInBackground` of `AsyncTask`). It needs to be run on the UI thread as it changes the UI. Right? – Shobhit Puri Sep 13 '13 at 23:52
  • The `Asynctask` was created just to solve this kind of problem. In the `AsyncTask` `onPostExecute()` your `boolean installed` returned from the `SharedPreferences` can determent if the `AlertDialog` should be showed. The `onPostExecute()` is running on the main UI thread and the `doInBackground()` is not. This is basic Android ways to do stuf – Erik Sep 13 '13 at 23:59
  • I get your point but the advantage of `AsyncTask` lies in `doInBackground` right? Otherwise if you create a dialog in `onCreate()` or inside `onPostexecute`, the code is running on the same UI thread. What difference would be make then? – Shobhit Puri Sep 14 '13 at 00:04
  • This might be more of a design issue. One can argue that `SharedPrefence` part can be put in background. If it was a `SQLlite` database operation, then I agree it would be a perfect design to get the data from database from within `doInBackground`. But, SharedPreference is very fast as compared to database. That's why it was created to avoid database calls for everything. – Shobhit Puri Sep 14 '13 at 00:05
  • Read my link on `AsyncTask` and activity-life-cycle. The `onPostexecute()` is decoupled from the main ui thread running in parallel. Here is where you do the `settings.getBoolean("in...` and send the result to onPostexecute() witch is running on main Ui thread. Source [Android Activity](http://developer.android.com/reference/android/app/Activity.html) – Erik Sep 14 '13 at 00:17
  • In onCreate() the Activity has not even become visible and you want to pop up an AlertDialog into something that that not even exist. [click me](http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle) – Erik Sep 14 '13 at 00:33
  • so I put `final SharedPreferences settings = getSharedPreferences("pref_name", 0); boolean installed = settings.getBoolean("installed", false);` in the `doInBackGround` and then I put the rest in the `onPostExecute` – Inman Douche Sep 14 '13 at 01:25
  • 1
    No, this is definitely not what `AsyncTask` was designed for and there is nothing wrong with doing what the OP is doing in the `onCreate()` – codeMagic Sep 16 '13 at 23:03
  • Showing an `AlertDialog` in `onCreate()` will crash the program maybe you didn't read the question totaly. `AsyncTask` is fine even for smaller thing but och we can meet halfways by moving all code in `onCreate()` except the `final EditText et =` and place the code in `onResume()` – Erik Sep 17 '13 at 11:59
  • There is no difference if you have it in `onCreate()` or `onResume()`. Besides the fact of how often it may be called. An `AlertDialog` is perfectly fine in `onCreate()`...give it a try – codeMagic Sep 17 '13 at 22:50
  • Your are right it do show up but how do you fix the window leaks – Erik Sep 18 '13 at 07:41
  • 1
    You close the `Dialog` if it is showing before the `Activity` is destroyed or something comes on top. You can do this in `onPause()` if it is a problem – codeMagic Sep 18 '13 at 12:45
0

What you have is as follows:

if(!installed){
    // Show dialog 
    // Else Everything inside it
}

When your app starts first time, it goes inside loop and shows the dialog. Next time when you restart, the value the SharedPreference is true, so it does not go inside the loop and nothing happen. On restarting the phone/emulator ShraredPreference does not delete, so is still true and does not go inside the loop, so nothing happens.

If you do the indentation of your program clearly, then it might be visible in bettr way.

Shobhit Puri
  • 25,769
  • 11
  • 95
  • 124