1

I have designed an application for android, in which i am showing a splash screen before the main activity is started but the application takes 5-7 seconds to start on low-end devices. I want to reduce that time to as low as possible. I have been trying to reduce the things to be done in onCreate() but now i cannot remove any thing more from that. I am pasting the code that i have used to show the splash and the code from MainActivity. Please help me in reducing the startup time of the application.

Splash.java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_splash);
    txtLoad = (TextView) findViewById(R.id.txtLoading);
    txtLoad.setText("v1.0");

    new Thread() {
        public void run() {
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                finish();
                Intent intent = new Intent(SplashActivity.this,MainActivity.class);
                startActivity(intent);
            }
        }
    }.start();
}

MainActivity.java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_main);
    editType1UserName = (EditText) findViewById(R.id.editTextType1UserName);
    editType1Password = (EditText) findViewById(R.id.editTextType1Password);
    editType2UserName = (EditText) findViewById(R.id.editTextType2UserName);
    editType2Password = (EditText) findViewById(R.id.editTextType2Password);
    editType3UserName = (EditText) findViewById(R.id.editTextType3UserName);
    editType3Password = (EditText) findViewById(R.id.editTextType3Password);
    editType4UserName = (EditText) findViewById(R.id.editTextType4UserName);
    editType4Password = (EditText) findViewById(R.id.editTextType4Password);
    mTxtPhoneNo = (AutoCompleteTextView) findViewById(R.id.mmWhoNo);
    mTxtPhoneNo.setThreshold(1);
    editText = (EditText) findViewById(R.id.editTextMessage);
    spinner1 = (Spinner) findViewById(R.id.spinnerGateway);
    btnsend = (Button) findViewById(R.id.btnSend);
    btnContact = (Button) findViewById(R.id.btnContact);
    btnsend.setOnClickListener((OnClickListener) this);
    btnContact.setOnClickListener((OnClickListener) this);
    mPeopleList = new ArrayList<Map<String, String>>();
    PopulatePeopleList();
    mAdapter = new SimpleAdapter(this, mPeopleList, R.layout.custcontview,
            new String[] { "Name", "Phone", "Type" }, new int[] {
                    R.id.ccontName, R.id.ccontNo, R.id.ccontType });
    mTxtPhoneNo.setAdapter(mAdapter);
    mTxtPhoneNo.setOnItemClickListener((OnItemClickListener) this);
    readPerson();
    Panel panel;
    topPanel = panel = (Panel) findViewById(R.id.mytopPanel);
    panel.setOnPanelListener((OnPanelListener) this);
    panel.setInterpolator(new BounceInterpolator(Type.OUT));
    getLoginDetails();

}
Tapan Desai
  • 848
  • 2
  • 14
  • 36
  • What do you do in the `PopulatePeopleList()` method? If you're querying the contacts provider on the phone(and by the looks of your code this is what you do) I hope you do it in a `CursorLoader` otherwise you could have problems with the performance like you see. – user Oct 07 '12 at 07:56
  • @Luksprog yes i am using contacts provider in `PopulatePeopleList`.. can you explain me about what is cursor loader and also how i devrease the app start up time. – Tapan Desai Oct 07 '12 at 08:16
  • 1
    It may be a good idea to just put a splash screen in. Then users of the app don't actually think it is a slow load up because they're concentrating on your splash screen and once that's finished, the app is just there all loaded perfectly. – edwoollard Oct 07 '12 at 10:42
  • 1
    @edwoollard You should strive to avoid a splash screen(unless you build games or other heavy initialization applications), this is important for the user experience. In this question's particular case there is absolutely no need for a splash screen. – user Oct 07 '12 at 11:26

1 Answers1

3

The reason you have that slowdown is because you most likely query the contacts provider on the phone, extract some data from those queries, put them in mPeopleList and then set it to your SimpleAdapter. So your activity's onCreate method waits until PopulatePeopleList() finishes its job. I don't know how you query that contacts provider but see if you can't adapt your code to use a CursorLoader(available in older android version through the compatibility package). This will mean that you would have to switch to a Cursor based adapter, possible other changes depending on your code.

If you still want to use a non based SimpleAdapter you'll need to override it them implement your own AsyncTaskLoader(again available in older android version through the compatibility package):

public class ContactsDataLoader extends
        AsyncTaskLoader<ArrayList<Map<String, String>>> {

    public ContactsDataLoader(Context context) {
        super(context);     
    }

    @Override
    public ArrayList<Map<String, String>> loadInBackground() {
        // here do what you do in the PopulatePeopleList() method
        // this will be done in another thread so the activity will initially
        // start empty(set an empty mPeoples list to the SimpleAdapter) and as
        // this loader finishes its job you'll have the list filled with the
        // data that is returned here
        return data;
    }

    @Override
    protected void onStartLoading() {
        super.onStartLoading();
        forceLoad();
    }

}

Then you'll have the activity where you need this data, implement LoaderManager.LoaderCallbacks<ArrayList<Map<String, String>>> :

public class MainActivity implements LoaderManager.LoaderCallbacks<ArrayList<Map<String, String>>>

interface that needs this methods defined:

@Override
    public Loader<ArrayList<Map<String, String>>> onCreateLoader(int id,
            Bundle args) {
        return new ContactsDataLoader(context);
    }

    @Override
    public void onLoadFinished(Loader<ArrayList<Map<String, String>>> loader,
            ArrayList<Map<String, String>> data) {
        // your custom adapter will need a method to update its data
        adapter.changeData(data);
        // you always have the option of using a normal SimpleAdapter and create
        // a new instance each time the data changes
        // mPeopleList = data;
        // mAdapter = new SimpleAdapter(this, mPeopleList,
        // R.layout.custcontview,
        // new String[] { "Name", "Phone", "Type" }, new int[] {
        // R.id.ccontName, R.id.ccontNo, R.id.ccontType });
        // mTxtPhoneNo.setAdapter(mAdapter);
    }

    @Override
    public void onLoaderReset(Loader<ArrayList<Map<String, String>>> loader) {
        // your custom adapter will need a method to update its data
        adapter.changeData(null); // or an empty list of data
        // you always have the option of using a normal SimpleAdapter and create
        // a new instance each time the data changes
        // mPeopleList = new ArrayList<Map<String, String>>;
        // mAdapter = new SimpleAdapter(this, mPeopleList,
        // R.layout.custcontview,
        // new String[] { "Name", "Phone", "Type" }, new int[] {
        // R.id.ccontName, R.id.ccontNo, R.id.ccontType });
        // mTxtPhoneNo.setAdapter(mAdapter);
    }

Then all you have to do is call:

// mPeopleList will have to be initialized to an empty list in the `onCreate` method
getLoaderManager().initLoader(0, null, this); 

in your onCreate method. The app will start pretty fast but will have it's list empty initially until the loader manages to do it's work and get the data from the contacts and set it to your adapter.

user
  • 86,916
  • 18
  • 197
  • 190
  • i didn't understand this part of your answer `Then you'll have the activity where you need this data, implement LoaderManager.LoaderCallbacks>> , interface that needs this methods implemented:` – Tapan Desai Oct 07 '12 at 09:32
  • thanks for sparing your time but when i wrote this `public class MainActivity implements LoaderManager.LoaderCallbacks>>` i am getting the error `LoaderManager cannot be resolved to a type` – Tapan Desai Oct 07 '12 at 09:38
  • after implementing your suggestion now i am getting a new error. `Error: java.lang.NullPointerException at android.support.v4.content.Loader` pls see this thread http://stackoverflow.com/questions/12792953/error-java-lang-nullpointerexception-at-android-support-v4-content-loader – Tapan Desai Oct 09 '12 at 09:21