2017-03-20 4 views
2

Androidのアクティビティとフラグメントがちょっと乱雑になってきています。そして、私はいくつかの良いコーディング方法を適用したいと思います。しかし、私は良いソリッドデザインを思いつくたびに、Androidは方法で取得します!Androidインテントへのコールの抽象化

私は具体的な例として、ユーザーが詳細(名前、電子メールなど)を更新できるようにするための断片を持っています。また、プロフィール写真として使用するために写真を撮ることもできます。

私は、この「写真撮影」コードを別のインターフェイスに移動したいと考えています。それをPhotoTakerとしましょう。次に、正しいインテントを開始し、撮影した画像のファイル名を返すために、このインタフェースを実装するAndroidPhotoTakerというクラスが必要です。

public interface PhotoTaker { 
    Uri capturePhoto(); 
} 

public class AndroidPhotoTaker implements PhotoTaker { 
    private Context _context; 

    @Inject 
    public AndroidPhotoTaker(Context context) { 
     _context = context; 
    } 

    @Override 
    public Uri capturePhoto() { 
     Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
     if (takePictureIntent.resolveActivity(_context.getPackageManager()) != null) { 
      File photoFile = new File("some/path/to/a/file"); 

      Uri photoUri = FileProvider.getUriForFile(_context, _context.getApplicationContext().getPackageName() + ".provider", photoFile); 
      takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); 
      _context.startActivity(takePictureIntent); 
      return photoUri; 
     } 

     return null; 
    } 
} 

Dagger2経由で正しいコンテキストが注入されたとします。

私の問題は、私がフラグメントで行ったように私がもはやstartActivityForResult()を呼び出すことができないということです。したがって、私は結果を処理するためにもはやonActivityResult()コールバックを持っていません。私が実際に見つけることができる唯一のものは_context.startActivity()ですが、そうは思わしくありません。

コールバックはありません。将来的にこれらのインテントから余分なデータを取得したいと考えています。

この問題を他の人がどのように解決しましたか?ここでの一般的な解決策は何ですか?つまり、コールバックを持つAndroidのインテントコールをどのように抽象化しますか?私の意見で

答えて

0

calback処理がはるかコーディングがあまりにも複雑に抽象化:あなたがあなた自身の 活動基底クラスAndroidはonActivityResult(に対して行う呼び出しをキャッチ)を実装し、あなたの自己定義にこれらの呼び出しを転送する必要があります ホスティングアクティビティで実装する必要があるIOnActivityResultインターフェイス。

代わりに、インテントを作成して分析する静的メソッドを持つヘルパークラスを作成できます。私のアプリで

public class MyPhotoTakerClientActivity extends Activity { 

    private void onTakePhotoClicked() { 
     Intent takePictureIntent = PhotoTakerHelper.createIntent("some/path/where/to/store/the/resultfile.jpg"); 
     if (PhotoTakerHelper.canProcess(this, takePictureIntent)) { 
      startActivityForResult(takePictureIntent, TakePhotoID); 
     } else { 
      ... error processing 
     } 
    } 

    protected void onActivityResult(final int requestCode, 
            final int resultCode, final Intent intent) { 
     super.onActivityResult(requestCode, resultCode, intent); 

     switch (requestCode) { 
      case TakePhotoID : 
       Uri uri = PhotoTakerHelper.getPhotoUri(intent); 
       showPhoto(uri); 
       break; 
      ... 

すべての活動は、サブアクティビティに呼び出し元のアクティビティから移動できるすべてのパラメータ受け取る静的メソッドshowActivityあります

public class FotoGalleryActivity extends Activity { 
    public static void showActivity(Activity context, GalleryFilterParameter filter, 
         QueryParameter query, int requestCode) { 
     Intent intent = new Intent(context, FotoGalleryActivity.class); 

     if (filter != null) { 
      intent.putExtra(EXTRA_FILTER, filter.toString()); 
     } 

     if (query != null) { 
      intent.putExtra(EXTRA_QUERY, query.toReParseableString()); 
     } 

     if (requestCode != 0) { 
      context.startActivityForResult(intent, requestCode); 
     } else { 
      context.startActivity(intent); 
     } 
    } 
} 

を呼び出し元の活動がどのように知っている必要はありません。パラメータは移動する。必要なのは、FotoGalleryActivity.showActivity(getActivity(), getFilter(), null, ID_GALLERY);

+0

への呼び出しです。これは単体テストのためのどんなモックをも妨げるでしょうか?つまり、ユニットテストのためにインテントを開始したくありません。 私は今Android用の単体テストを試みていますが、 – blowfly

+0

私は同意します、静的メソッドはunittest-mockingを不可能にします。しかし、私は "unittest"アンドロイドのアクティビティの相互作用をdonotしません。コードを非静的にすることは自由です – k3b