javaandroidandroid-fragmentsandroid-asynctask

How to associate Fragment with no UI to the MainActivity


I have MainActivity.java that implements an interface from SshFragment.java which runs an AsyncTask in the fragment. The fragment has no UI but I'm unsure how to define it so and I'm confused how to load the fragment into the main activity.

public class MainActivity extends AppCompatActivity implements
        SshFragment.SshTaskListener {
    ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // setup/handle retained SshFragment
        final String SSH_FRAGMENT_TAG = "SSH_FRAGMENT";
        if (savedInstanceState == null) {
            // The Activity is NOT being re-created so we can instantiate a new Fragment
            // and add it to the Activity
            sshFragment = new SshFragment();

            getSupportFragmentManager()
                    .beginTransaction()
                    // It's almost always a good idea to use .replace instead of .add so that
                    // you never accidentally layer multiple Fragments on top of each other
                    // unless of course that's your intention
                    .replace(R.id.ssh_fragment, sshFragment, SSH_FRAGMENT_TAG)
                    .commit();
        } else {
            // The Activity IS being re-created so we don't need to instantiate the Fragment or add it,
            // but if we need a reference to it, we can use the tag we passed to .replace
            sshFragment = (SshFragment) getSupportFragmentManager().findFragmentByTag(SSH_FRAGMENT_TAG);
        }

I run my app and I get..

FATAL EXCEPTION: main
  Process: com.example.atest, PID: 11547
  java.lang.IllegalArgumentException: No view found for id 0x7f0801f2 (com.example.atest:id/ssh_fragment) for fragment SshFragment{370be34} (d598c437-ff65-47ea-88a9-e764647d34f9 id=0x7f0801f2 tag=SSH_FRAGMENT)
    at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:513)

Do I need to define a layout for the fragment? Or do I define it anywhere in my main_activity.xml like so?

<FrameLayout
    android:id="@+id/ssh_fragment"/>

But it complains I don't have height or width defined.

Do I still need to have an..

@Override
public View onCreateView(){}

in my fragment class? What would it be to define a no UI fragment?


Solution

  • You probably should be something more current than a headless fragment with an AsyncTask, but to answer your question:

    Since the fragment has no view, you would use the add method that does not require a view id instead of replace which is to swap one existing fragment in a view container with another.

    getSupportFragmentManager()
        .beginTransaction()
        .add(sshFragment, SSH_FRAGMENT_TAG)
        .commit();