0

I'm not that much experienced in Android, so every piece of code I have written so far was very simple. Now I need to implement a localization and navigation application, so I need to break my code into modules so that I can change each component alone. I have some variables that I need to share them between different classes. I used static variables but I read in some posts here that static variables are not preferred. Then I found some other posts talking about Context. So I created a class named Globals and I added the following lines in my Manifest file:

 <application android:name="com.example.smartnav.Globals" 
  package="com.example.smartnav"
 android:icon="@drawable/ic_launcher"
 android:allowBackup="true"

   android:label="@string/app_name"/>

And here is the Globals Class :

    package com.example.smartnav;


import java.util.List;

import android.net.wifi.ScanResult;

import android.app.Application;

public class Globals extends Application {
      private Boolean Scanning=false;
      private String Logname;
      private int interval;
      private int numOfScans;
      private List<ScanResult> result;



      //getters
      public Boolean getScannig(){
        return Scanning;
      }
      public int getInterval()
      {
          return interval;
      }
      public int getScans()
      {
          return numOfScans;
      }
      public List<ScanResult> getRes()
      {
          return result;
      }
      public String getLog()
      {
          return Logname;
      }


    //setter

      public void setScanning(Boolean s){
        Scanning= s;
      }
      public void setRes(List<ScanResult> res)
      {
          result =res;
      }
      public void setInterval(int I)
      {
          interval = I;
      }
      public void setScans(int S)
      {
          numOfScans=S;
      }
      public void setLog(String s)
      {
          Logname= s;
      }

}

Now I have two questions, the first one is that my application keeps crashing whenever I try to use the Globals class, here is the code: Did I use context incorrectly?

    public class MainActivity extends Activity {

    private Context context;
    public WifiManager Wifi;
    private  WifiReceiver receiverWifi;
    private IntentFilter filter;
    private List<ScanResult> result;
    private File AppDir;
    private static String filename;
    private File file;
    private FileWriter writer;
    private Globals AppState ;
    private int Interval;
    private int numOfScans;


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

        Log.d("Main ","activity created");
        //
       AppState = ((Globals)getApplicationContext());
       context= this;
       Wifi=(WifiManager) getSystemService(Context.WIFI_SERVICE);
       receiverWifi = new WifiReceiver();
        filter= new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
        registerReceiver(receiverWifi, filter);

      Log.d("Main   ","wifi registered");
        // create the application directory

        AppDir = new File(Environment.getExternalStorageDirectory()+"/SmartNavi/Log");
        if(AppDir.isDirectory())
        {
            filename=Environment.getExternalStorageDirectory()+"/SmartNavi/Log/log.txt";
            file = new File(filename);
            if(!file.exists())
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            else 
            {
                Date d= new Date();
                filename=Environment.getExternalStorageDirectory()+"/SmartNavi/Log/log"+d.getTime()+".txt";
                file = new File(filename);
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            }
        else
        {
            AppDir.mkdirs();
            filename=Environment.getExternalStorageDirectory()+"/SmartNavi/Log/log.txt";
            file = new File(filename);
            if(!file.exists())
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            else 
            {
                Date d= new Date();
                filename=Environment.getExternalStorageDirectory()+"/SmartNavi/Log/log"+d.getTime()+".txt";
                file = new File(filename);
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }

        //setting pars

        Interval=250;
        numOfScans=4;
        AppState.setInterval(Interval);
        AppState.setScans(numOfScans);
        AppState.setLog(filename);


        Wifi.startScan();

        try {
                writer = new FileWriter(file, true);
                writer.append("Smart Navigation. \n");
                writer.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
       // AsyncScanning.AsyncScan();
    }//on create



    @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;
    }



    class WifiReceiver extends BroadcastReceiver {

        public void onReceive(Context c, Intent intent) {

            result=Wifi.getScanResults();
    //      AppState.setRes(result);
             try {
                writer = new FileWriter(file, true);
                writer.append(result.size()+" s \n");
                writer.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }//end of on receive

    }// end of class
} // end of smartNav

My last question is this : I have read on some answers here that if my application becomes a background process then all the data in the context will be set to null, and I will lose my context. Is there is any method to overcome this point? or should I switch to SharedPreferences ?

Edit :Here is the output of Logcat

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.smartnav/com.example.smartnav.MainActivity}: java.lang.ClassCastException: android.app.Application cannot be cast to com.example.smartnav.Globals

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Alaa
  • 539
  • 3
  • 8
  • 29

1 Answers1

1

Now I have two questions, the first one is that my application keeps crashing whenever I try to use the Globals class, here is the code: Did I use context incorrectly?

you should use getApplication() method for that, or make your application class singleton, so you would call Globals.getInstance().getMyVariable() etc.

My last question is this : I have read on some answers here that if my application becomes a background process then all the data in the context will be set to null, and I will lose my context. Is there is any method to overcome this point? or should I switch to SharedPreferences ?

if your app becomes background then Android is more likely to kill your app, and this way also destroy all your static objects. Inside your Globals class you should not store your data in static variables but rather in some persistant storage - if its small then use SharedPreferences, if its large then you can store it in json and save to application memory, or use sqlite db.

marcinj
  • 48,511
  • 9
  • 79
  • 100
  • I used it in the following line : AppState = ((Globals)getApplicationContext()); you mean that I should use getApplication instead of getApplicationContext() ? – Alaa Feb 22 '14 at 16:10
  • 1
    Yes, in this SO http://stackoverflow.com/questions/10607392/custom-global-application-class-breaks-with-android-app-application-cannot-be-c, you have an example – marcinj Feb 22 '14 at 16:17
  • now about using SharedPrefernces for now I have 5 variables as you can see in Globals class, should I switch to sharedPreferences or I should be fine with context? – Alaa Feb 22 '14 at 16:19
  • I used the context in the same way in the link you gave but it crashes when it reaches accessing the context , the problem is not solved yet @marcin_j – Alaa Feb 22 '14 at 16:31
  • You mean ((Globals)getApplication()) fails either? Maybe you have some error in manifest, you can change name to `com.example.smartnav.Globals`, also your label with ".." looks strange to me. As for variables, put there everything that must survive app being force closed, in my opinion this means putting there all your variables. – marcinj Feb 22 '14 at 17:13
  • I changed the label, but it keeps crashing, the logcat is added to the post can you tell me why this is happening ? – Alaa Feb 22 '14 at 17:43
  • 1
    Sorry, I have no idea, your logcat is clear: java.lang.ClassCastException: android.app.Application cannot be cast to com.example.smartnav.Globals. It means you have not properly implemented `android.app.Application` class or you have some error in your manifest. Check if in ` – marcinj Feb 22 '14 at 18:25
  • I have modified the manifest file as you said and added package="com.example.smartnav" I edited the post to reflect it , but the same problem is there, can you edit your answer to show me what the manifest file should look like? – Alaa Feb 22 '14 at 19:35
  • You should generate your app manifest using eclipse template, also package should be in manifest element, anyway its mandatory parametr. If you cant get application object to work make a singleton class, you will find lots of samples on google. – marcinj Feb 22 '14 at 21:30