2016-12-06 3 views
5

런타임에 권한을 요청해야하는 Android 앱을 개발 중입니다. Model-View-Presenter 아키텍처를 사용하여 구현하는 가장 좋은 방법에 대해 궁금합니다.MVP 아키텍처를 사용하여 런타임에 사용 권한을 확인하는 가장 좋은 방법은 무엇입니까?

내 생각은 발표자가 사용 권한을 담당하는 구성 요소 (예 : PermissionHandler)를 호출하고 적절하게 뷰를 업데이트하도록하는 것이 처음 생각이었습니다.

사용 권한을 확인하는 코드가 Activity 클래스와 밀접하게 결합되어 있습니다. 여기 활동이나 문맥을 필요 관련된 몇 가지 방법은 다음과 같습니다

  • ContextCompat.checkSelfPermission()
  • ActivityCompat.shouldShowRequestPermissionRationale()
  • ActivityCompat.requestPermissions()
  • onRequestPermissionsResult() 이것은 내가 통과해야 의미

(콜백) presenter를 Android 코드에서 무료로 유지하는 것이 testin에 좋다고 들었 기 때문에 내가별로 좋아하지 않는 발표자에게 지.

그로 인해, 나는 (액티비티에서) 뷰 레벨에서 권한을 처리하는 것에 대해 생각했지만, 비즈니스 로직이없는 UI 업데이트에 대해서만 책임지는 뷰를 떠나는 목적을 해칠 것이라고 생각합니다.

가능한 한 코드를 분리하고 유지 관리해야하는 문제를 해결하기위한 최선의 방법이 무엇인지 확신 할 수 없습니다. 어떤 아이디어?

답변

7

내가 뭘 할 것은 :

뷰가 구현됩니다

public Activity getViewActivity(); 

발표자가 구현됩니다

public void requestPermissions(); 
public void onPermissionsResult(); 

requestPermissions 내부 발표자가 수행합니다 getViewActivity().checkSelfPermission; getViewActivity.requestPermissions(); etc.

보기는에서 호출됩니다.presenter.onPermissionsResult();에 대한 콜백

이 모든 로직은 발표자 내부에서 구현됩니다.

내 의견으로는 발표자가 분리되어 있습니다.보기 구현에 의존하지 않습니다 (보기 인터페이스에만 의존).

"발표자를 Android 코드에서 자유롭게 유지하는 것이 테스트에 좋은 것이라고 들었습니다." 나는이 부분을 이해하지 못한다. 코드가 좋으면 문제없이 테스트 할 수 있습니다.

+0

이 방법이 안전한가요? 메모리 누수가 발생하지 않아야합니까? – fobo66

1

여전히 액세스 권한/요청을 모의 할 수있는 경우 여전히 PermissionHandler과 같은 것을 만들지 만보기 클래스 내에서만 참조하십시오.

public interface PermissionsHandler { 
    boolean checkHasPermission(AppCompatActivity activity, String permission); 
    void requestPermission(AppCompatActivity activity, String[] permissions, int requestCode); 
} 

생산 구현 :

public class PermissionsHandlerAndroid implements PermissionsHandler { 
    @Override 
    public boolean checkHasPermission(AppCompatActivity activity, String permission) { 
     return ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED; 
    } 

    @Override 
    public void requestPermission(AppCompatActivity activity, String[] permissions, int requestCode){ 
     ActivityCompat.requestPermissions(activity, permissions, requestCode); 
    } 
} 

조롱 클래스 (예를 들어, 테스트 활동이 제대로 onRequestPermissionsResult을 처리합니다 있는지 확인하기 위해)

public class PermissionsHandlerMocked implements PermissionsHandler { 
    @Override 
    public boolean checkHasPermission(AppCompatActivity activity, String permission) { 
     return false; 
    } 

    @Override 
    public void requestPermission(AppCompatActivity activity, String[] permissions, int requestCode){ 
     int[] grantResults = new int[permissions.length]; 
     for (int i = 0; i < permissions.length; i++) { 
      grantResults[i] = PackageManager.PERMISSION_GRANTED 
     } 
     activity.onRequestPermissionResult(requestCode, permissions, grantResults); 
    } 
} 

인터페이스 - 예를 들어, 그런 다음 활동 내역 :

fobo66

PermissionsHandler permissionsHandler; 

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

    permissionsHandler = Injection.providePermissionsHandler(); 
    //or however you choose to inject your production vs mocked handler. 
} 

//method from your view interface, to be called by your presenter 
@Override 
void requestLocationPermission() { 
    permissionsHandler.requestPermision((AppCompatActivity) this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_CODE_LOCATION}; 
} 
, 당신은 항상보기 checkLocationPermissionGranted()requestLocationPermission() 같은 훨씬 더 일반적인 메소드를 구현 할 수 있습니다. 그런 다음보기 구현은 필요에 따라 활동을 참조 할 수 있으며 발표자는 활동 참조를 만질 필요가 없습니다.