티스토리 뷰

Android 공부에 사용하는 참고서가 2019년 개정판이라 액티비티를 띄울 때마다 startActivityForResult 메서드를 호출하여 그 결과 값을 가져온다.

 

deprecated 메서드를 호출할 때마다, 괜히 헛공부하는 느낌이 들어서 Android 에서 권장하는 액티비티의 결과 값을 참조하는 방법을 좀 정리해보려고 한다. 

 

예제는 직전에 사용했던 앨범에서 이미지를 가져오는 예제 코드를 비교를 위해 사용하겠다.


◎(기존) MainActivity.java

package com.example.samplealbum;

import android.app.Activity;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.yanzhenjie.permission.Action;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.runtime.Permission;

import java.io.InputStream;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    ImageView imageView;

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

        AndPermission.with(this)
                .runtime()
                .permission(Permission.READ_EXTERNAL_STORAGE)
                .onGranted(new Action<List<String>>() {
                    @Override
                    public void onAction(List<String> permissions) {
                    }
                })
                .onDenied(new Action<List<String>>() {
                    @Override
                    public void onAction(List<String> permissions) {
                    }
                })
                .start();

        imageView = findViewById(R.id.imageView);


        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openGallery();
            }
        });
    }

    public void  openGallery() {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);

        startActivityForResult(intent, 101);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(requestCode == 101) {
            if(requestCode == RESULT_OK) {
                Uri fileUri = data.getData();

                ContentResolver resolver = getContentResolver();

                try{
                    InputStream inputStream = resolver.openInputStream(fileUri);
                    Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                    imageView.setImageBitmap(bitmap);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

해당 방식은 책에서 나온 그대로의 방식으로 startActivityForResult 메서드로 액티비티를 참조한 뒤, 그 결과 값을 콜백 메서드인 onActivityResult에서 활용하는 방식이다. 

 

하지만 이때, 결과를 얻기 위해  startActivity가 아닌  startActivityForResult 메서드를 호출하여 결과를 얻기 위한 활동을 시작할 때 메모리 부족 현상이 발생한다면 프로세스와 활동 자체가 소멸할 수 있는 가능성이 있기 때문에 안드로이드에서는 해당 방식을 권장하지 않는다.

 

해당 내용은 여기 에서 확인할 수 있다.

 

그럼 어떻게 해야 startActivity() 를 사용하면서 액티비티 활동의 결과 값을 참조할 수 있을까?

 

제네릭 타입의

ActivityResultLauncher<?>

객체를 사용해야 한다.

 

해당 객체는 Activity Result AIP에서 제공하는 registerForActivityResult() 메서드를 호출하여 반환 받으면 되는데, 이 메서드는 startActivityForResult메서드와 같이 해당 결과 값을 가져와서 활동을 할 결과 콜백을 등록할 수 있게 해준다.

 

◎(registerForActivityResult사용) MainActivity.java

package com.example.ssssssdead;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.yanzhenjie.permission.Action;
import com.yanzhenjie.permission.AndPermission;
import com.yanzhenjie.permission.runtime.Permission;

import java.io.InputStream;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    ImageView imageView;

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

        AndPermission.with(this)
                .runtime()
                .permission(Permission.READ_EXTERNAL_STORAGE)
                .onGranted(new Action<List<String>>() {
                    @Override
                    public void onAction(List<String> permissions) {
                    }
                })
                .onDenied(new Action<List<String>>() {
                    @Override
                    public void onAction(List<String> permissions) {
                    }
                })
                .start();

        imageView = findViewById(R.id.imageView);


        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openGallery();
            }
        });
    }

    public void  openGallery() {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);

        mGetContent.launch(intent);
        startActivity(intent);
    }


    ActivityResultLauncher<Intent> mGetContent = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            new ActivityResultCallback<ActivityResult>() {
                @Override
                public void onActivityResult(ActivityResult result) {
                    if(result.getResultCode() == Activity.RESULT_OK) {
                        Intent data = result.getData();

                        Uri fileUri = data.getData();

                        ContentResolver resolver = getContentResolver();

                        try{
                            InputStream inputStream = resolver.openInputStream(fileUri);
                            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                            imageView.setImageBitmap(bitmap);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
}

 

 

Comments