-3

I have two classes corresponding to two activities in my code. What I would like, is that the functions in the class of the activity B is launched in the activity A, but without showing the activity : I would just like the code to be executed...

How can I launch the functions of the activity B in background from the activity A? I read to use Services, but I don't know at all how to use them, I don't see so many reading about it. I don't know if it is the good way. I tried this with no success: startService(new Intent(this, HereMap.class));

Activity A:

public class LoginActivity extends AppCompatActivity {
@Override
    protected void onResume(){
...

//Code to execute the activity B in background Intent activityB= new Intent(this, HereMap.class); activityB.onDownloadButtonClicked(); //=> here is the execution but doesn't work...

}
    @Override
    protected void onCreate(Bundle savedInstanceState) {
...
}

Activity B:

        public class HereMap extends AppCompatActivity {
...

         private MapLoader.Listener mapLoaderHandler = new MapLoader.Listener() {
     


            @Override
            public void onProgress(int progress) {
                Log.i(TAG, "Progress " + progress + "%");
                downloadProgressBar.setProgress(progress);
            }
    
            @Override
            public void onInstallationSize(long diskSize, long networkSize) {
                Log.i(TAG, "Map data require " + diskSize);
            }
    
            @Override
            public void onGetMapPackagesComplete(MapPackage rootMapPackage,
                                                 MapLoader.ResultCode resultCode) {
                if (resultCode == MapLoader.ResultCode.OPERATION_SUCCESSFUL) {
                    Log.i(TAG, "Map packages received successful: " + rootMapPackage.getTitle());
    
                    currentInstalledMaps = new ArrayList<>(1);
                    populateInstalledMaps(rootMapPackage);
                } else {
                    Log.e(TAG, "Can't retrieve map packages: " + resultCode.name());
                    Toast.makeText(HereMap.this,
                            "Error: " + resultCode.name(), Toast.LENGTH_SHORT).show();
                    return;
                }

...

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //Init map
        setContentView(R.layout.activity_here_map);
        mapFragment = (AndroidXMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapfragment);

...

    public void onDownloadButtonClicked() {
        Log.d(TAG, "Downloading new map data...");

        List<Integer> downloadList = new ArrayList<>(1);
        downloadList.add(120214);    //Id:120002 Berlin  Id:120214, Name: Andalucia, Size:231504 Cherche l'id avec l'application iOS map-downloader-ios-swift

        downloadProgressBar.setProgress(0);
        downloadProgressBar.setVisibility(View.VISIBLE);
        MapLoader.getInstance().installMapPackages(downloadList);
    }
ΩlostA
  • 2,501
  • 5
  • 27
  • 63
  • If you have code you want to share between the fragments/activities then it should not live in a specific activity or fragment. Move it to some other helper class so you can call it from both places as-needed. – Tyler V Aug 27 '22 at 16:06
  • @TylerV Exactly, but how to get a specific class with all the functions, and call it from the activity, it is the same problem – ΩlostA Aug 27 '22 at 17:43

1 Answers1

1

If you have some function you want to use in multiple Activities, you can put it in its own class and instantiate that class in whatever place you need to call its methods. The created class should not extend Activity or Fragment if it isn't actually an Activity or Fragment (this will cause all sorts of bugs). If it needs access to a Context or other Android component, you could pass those in at construction or to the methods that need it.

If you need your helper class to interact with its hosting activity (e.g. show or hide views, send data to views, etc) you can define interfaces on the helper or pass the views in directly.

If you define interfaces on your helper class you can use those to "call back" to whatever activity is hosting it (e.g. to show a progress bar). If you don't want to use an interface you could just pass the view to the helper class too, but the interface approach is sometimes more flexible.

Here are examples of both approaches:

Using an Interface

public class MapHelper {
    public interface ProgressBarHolder {
        void showBar();
    }

    private ProgressBarHolder progress;

    MapHelper(ProgressBarHolder prog) {
        progress = prog;
    }

    public void onDownloadButtonClicked() {
        List<Integer> downloadList = new ArrayList<>(1);
        downloadList.add(120214);
        progress.showBar();
        MapLoader.getInstance().installMapPackages(downloadList);
    }
}

then you can call it from any Activity, like this

public class MyActivity extends AppCompatActivity 
       implements MapHelper.ProgressBarHolder 
{
    private MapHelper helper = new MapHelper(this);
    private ProgressBar bar;

    @Override
    public void showBar() {
        // show a progress bar, MapHelper will call this
        // when it needs the current activity to show a progress bar
        bar.setProgress(0);
        bar.setVisibility(View.VISIBLE);
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
     
        // set up stuff

        bar = findViewById(R.id.progress);
        bar.setVisibility(View.GONE);

        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                helper.onDownloadButtonClicked();
            }
        });        
    }
}

Passing in Views

public class MapHelper {
    private ProgressBar progress;

    MapHelper(ProgressBar prog) {
        progress = prog;
    }

    public void onDownloadButtonClicked() {
        List<Integer> downloadList = new ArrayList<>(1);
        downloadList.add(120214);
        progress.setProgress(0);
        progress.setVisibility(View.VISIBLE);
        MapLoader.getInstance().installMapPackages(downloadList);
    }
}

then you can call it from any Activity, like this

public class MyActivity extends AppCompatActivity {
    private MapHelper helper;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
     
        // set up stuff

        ProgressBar bar = findViewByid(R.id.progress);
        bar.setVisibility(View.GONE);

        // Wait to create the helper until you have the views
        helper = new MapHelper(bar);

        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                helper.onDownloadButtonClicked();
            }
        });        
    }
}
Tyler V
  • 9,694
  • 3
  • 26
  • 52
  • Thank you very much, I am going to test it and I will tell you :) – ΩlostA Aug 27 '22 at 22:56
  • @Thank you, it works. I have a problem, but it concerns another point on this class: https://stackoverflow.com/q/73570867/3581620 – ΩlostA Sep 01 '22 at 14:15