Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static Array Adapter in Fragment. Good or bad practice?

I've ton a ton of Google searches on static objects in Java and I think I understand how they work in Android. Static objects are GC'ed when the process of the app is terminated, not when the Activity that declares the static object is destroyed (correct me if I'm wrong). I have an app with a Tabhost that uses Fragments in it. The Fragment that declares the object is all the way to the right (there are three Fragments) of the ViewPager. The tab on the right has a ListView that displays user data and I would like that data to persist when the user swipes through all of the tabs or navigates away from the app. This data does not need to be saved, it just needs to remain in memory through normal use of the app. The fix that gives me the result I want is by setting a static prefix to my Array Adapter. My question is, is this considered good practice? I know that using static objects incorrectly can lead to memory issues however I didn't get any FC's with extensive use (landscape to portrait over and over, swiping quickly through the tabs, adding a lot of data to the ListView etc.). Here is the code that I am using

static ArrayAdapter<String> arrayAdapter;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
{

    View view = inflater.inflate(R.layout.fragment,
            container, false);      

        if (personList == null)
        {

            personList = new ArrayList<String>();

        }


        if (arrayAdapter == null)
        {

            arrayAdapter = new ArrayAdapter<String>
            (getActivity().getApplicationContext(), android.R.layout.simple_list_item_1, personList);

        }

EDIT:

This is how I am implementing this idea. I have this code in my main Activity (the one that parents the tab fragments. I put this code in the onDestroy() method of the activity to try and reclaim some memory.

@Override
protected void onDestroy() {
    super.onDestroy();

    if (arrayAdapter != null)
    {

        arrayAdapter.clear();

        arrayAdapter = null;

        Log.i("Activity", "Adapter nulled!");

    }


    Log.i("Activity", "Activityhas been destroyed");
}

public ArrayAdapter<String> getArrayAdapter(ArrayList<String> personList)
{

    arrayAdapter = new ArrayAdapter<String>
    (getBaseContext(), android.R.layout.simple_list_item_1, personList);

    Log.i("Activity", "Adapter Created");


    return arrayAdapter;
}

With this code in my Fragment

if (personList == null)
{

    personList = new ArrayList<String>();

}


if (arrayAdapter == null)
{

    arrayAdapter = ((ActivityMainScreen)getActivity()).getArrayAdapter(personList);

}
like image 835
John P. Avatar asked Dec 16 '22 17:12

John P.


1 Answers

Remember! Anything that consumes reference to your activity Context and is marked as STATIC is prone to memory leaks. It is highly not recommended. You may use some sort of Observer/Observable pattern to keep your data available in other classes or simple access the required objects via public methods defined in your TabHost activity.

For more info, read this http://developer.android.com/training/basics/fragments/communicating.html

Regarding memory leaks, perhaps you should test your current implementation on a low-end device because new model devices are pretty rich in terms of resources.


Your Activity:

private ArrayAdapter<String> arrayAdapter = null;

//initialize your adapter in onCreate

public ArrayAdapter<String> getListAdapter(){
    return arrayAdapter;
}

Your Fragment:

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    ArrayAdapter<String> adapter = ((YourActivityClass) getActivity()).getListAdapter();
    yourListView.setAdapter(adapter);
}
like image 111
waqaslam Avatar answered Jan 06 '23 17:01

waqaslam