2015-09-21 19 views
19

Tôi đang cố gắng kết nối chức năng Android của việc giữ màn hình trên React Native. Tôi nghĩ rằng tôi có thể làm điều này với một mô-đun đơn giản, tuy nhiên tôi không biết cách truy cập vào Hoạt động Android hiện tại từ mô-đun đã nói.Cách truy cập Hoạt động từ mô-đun Android Gốc Phản ứng?

Tôi cần tài liệu tham khảo Hoạt động vì vậy tôi có thể gọi .getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); vào nó

tôi đã cố gắng để có được hoạt động qua quá trình đúc như vậy ((Activity)getReactApplicationContext().getBaseContext()), nhưng điều này ném một "không thể được đúc để Android.app.Activity" lỗi

+0

Ví dụ liên quan đến giao tiếp giữa các thành phần gốc và Android. [Repo Link] (http://github.com/amalChandran/ReactNative_Android_integration) – amalBit

Trả lời

29

CustomReactPackage.java:

public class CustomReactPackage implements ReactPackage { 

    private Activity mActivity = null; 

    public CustomReactPackage(Activity activity) { 
     mActivity = activity; 
    } 

    @Override 
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) { 
     List<NativeModule> modules = new ArrayList<>(); 
     // Add native modules here 
     return modules; 
    } 

    public List<Class<? extends JavaScriptModule>> createJSModules() { 
     return Collections.emptyList(); 
    } 

    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { 
     List<ViewManager> modules = new ArrayList<>(); 
     // Add native UI components here 
     modules.add(new LSPlayerManager(mActivity)); 
     return modules; 
    } 
} 

LSPlayerManager là thành phần giao diện người dùng gốc của tôi. Tôi định nghĩa một constructor để tôi có thể vượt qua trong hoạt động:

public LSPlayerManager(Activity activity) { 
    mActivity = activity; 
} 

Và cuối cùng trong MainActivity.java nơi ReactInstanceManager được xác định, chúng ta có thể vượt qua các hoạt động để tùy chỉnh của chúng tôi Phản ứng gói:

mReactInstanceManager = ReactInstanceManager.builder() 
     .setApplication(getApplication()) 
     .setBundleAssetName("index.android.bundle") 
     .setJSMainModuleName("src/index.android") 
     .addPackage(new MainReactPackage()) 
     .addPackage(new CustomReactPackage(this)) // <--- LIKE THIS! 
     .setUseDeveloperSupport(BuildConfig.DEBUG) 
     .setInitialLifecycleState(LifecycleState.RESUMED) 
     .build(); 

CẬP NHẬT ĐỐI VỚI BẢN TIN TÁC ĐỘNG 0.29.0

Đây không còn là cách bạn truy cập hoạt động trong môi trường gốc dule.Xem https://github.com/facebook/react-native/releases/tag/v0.29.0 để được hướng dẫn di chuyển

+0

cảm ơn bạn .. Điều này đã giúp rất nhiều –

+0

Điều này chắc chắn là câu trả lời tốt nhất và chính xác những gì tôi đang làm trong dự án của riêng tôi. Trong trường hợp của tôi, tôi đang sử dụng máy quét mã QR ZXing được nhúng bên trong React Native và cần thiết cho cả việc khởi động quá trình quét và đọc kết quả (onActivityResult). Dưới đây là ý chính của mã của tôi trong trường hợp nó giúp bất kỳ ai có vấn đề tương tự - https://gist.github.com/mdp/a501edd93632f13fd9f8 –

+0

làm cách nào tôi có thể chuyển hoạt động hiện tại sang cách mới để thêm gói. return mảng. asList ( mới MainReactPackage(), mới ThePackageClass (điều này) <- điều này ở đây không hoạt động ); điều này không hoạt động ở đây. –

-1

Nó không phải là siêu rõ ràng từ https://github.com/facebook/react-native/blob/master/docs/NativeModulesAndroid.md, nhưng bạn có thể đọc mã nguồn của ToastModule trong bản phân phối gốc phản ứng để xem cách họ làm điều đó github.com/facebook/react-native/blob/daba14264c9f0d29c0327440df25d81c2f58316c/ReactAndroid/src/main/ java/com/facebook/phản hồi/mô-đun/bánh mì nướng/ToastModule.java # L31-L33

Ý tưởng là hoạt động chính sẽ được chuyển thành responseContext trong bộ khởi tạo cho mô-đun được gọi từ ReactInstanceManager.builder() gọi trong github.com/facebook/react-native/blob/3b4845f93c296ed93c348733809845d587227823/local-cli/generator- android/templates/package/MainActivity.java # L28 thông qua sự khởi tạo của MainReactPackage github.com/facebook/react-native/blob/daba14264c9f0d29c0327440df25d81c2f58316c/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java# L49

+0

Không giải thích cách lấy Hoạt động. – marcshilling

3

Đã sửa đổi:

Vấn đề là getReactApplicationContext() trả về ngữ cảnh của Ứng dụng chứ không phải hoạt động. Bạn không thể nhập một bối cảnh Ứng dụng vào một Hoạt động.

Đây là giải pháp đơn giản

Kể từ thường, có duy nhất một hoạt động (Main Hoạt động) trong phản ứng bản địa, Chúng tôi có thể viết một hàm tĩnh trong MainActivity trở lại hoạt động

private static Activity mCurrentActivity = null; 

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    mCurrentActivity = this; 
    ... 
} 
... 
public static Activity getActivity(){ 
    Activity activity = new Activity(); 
    activity = mCurrentActivity; 
    return activity; 
} 

sau đó gọi MainActivity.getActivity() từ các module cầu

+1

tác phẩm này, nhưng tôi giả sử bạn đã thấy nhận xét trên GitHub: https://github.com/facebook/react-native/issues/2996#issuecomment-142913032. Tôi đang sử dụng phương pháp đó và nó hoạt động rất tốt. Nếu bạn chỉnh sửa câu trả lời của bạn để mô tả phương pháp đó tôi sẽ chấp nhận nó. – marcshilling

+0

Tôi chưa xem xét việc tạo ra sự thực hiện của riêng tôi về ReactPackage. Vì bạn đã tìm ra nó, nó sẽ là một trợ giúp lớn cho cộng đồng nếu bạn có thể truyền đạt kiến ​​thức của bạn –

+0

chỉ cần đăng câu trả lời của riêng tôi. Kiểm tra nó ra và cho nó một thử. – marcshilling

11

Tôi đoán getCurrentActivity() phương thức ReactContextBaseJavaModule có thể được sử dụng như mã sau đã được sao chép từ React-Native mã gốc;

import android.app.Activity; 
import com.facebook.react.bridge.ReactContextBaseJavaModule; 

public class AwesomeModule extends ReactContextBaseJavaModule { 

    public AwesomeModule(ReactApplicationContext reactContext) { 
    super(reactContext); 
    } 

    @Override 
    public String getName() { 
    return "AwesomeAndroid"; 
    } 

    private static final String ERROR_NO_ACTIVITY = "E_NO_ACTIVITY"; 
    private static final String ERROR_NO_ACTIVITY_MESSAGE = "Tried to do the something while not attached to an Activity"; 

    @ReactMethod 
    public void doSomething(successCallback, errorCallback) { 

    final Activity activity = getCurrentActivity(); 

    if (activity == null) { 
     errorCallback(ERROR_NO_ACTIVITY, ERROR_NO_ACTIVITY_MESSAGE); 
     return; 
    } 

    } 

} 
+0

Nó hoạt động ok trong trường hợp của tôi – xwild

+2

Phương pháp đã bị xóa bn. có cách nào mới để làm điều này? Thanks .. –

+0

Liên kết tôi đã viết trong câu trả lời chỉ định repo chủ của "phản ứng bản địa" và nó có vẻ sống. Ngoài ra tôi đã cố gắng tìm bất cứ điều gì về việc loại bỏ nó tuy nhiên tôi không thể. Bạn có thể vui lòng chia sẻ thêm thông tin về nó? – efkan

0

Đối với 0,28 và trước đó, bạn có thể nhận được từ hoạt động ReactInstanceManagerImpl 's private @Nullable Activity mCurrentActivity;, 0.29+' s ReactContextBaseJavaModule sử dụng cùng lĩnh vực.

-1

Làm cách nào để chuyển hoạt động tới gói từ ReactApplication :: getPackages()?

Tôi không hiểu. Tôi không thể tìm thấy bất kỳ ví dụ rõ ràng nào

package com.bluetoothioexample; 

import android.app.Application; 
import android.util.Log; 

import com.facebook.react.bridge.ReactContextBaseJavaModule; 

import com.facebook.react.ReactApplication; 
import com.facebook.react.ReactInstanceManager; 
import com.facebook.react.ReactNativeHost; 
import com.facebook.react.ReactPackage; 
import com.facebook.react.shell.MainReactPackage; 

import java.util.Arrays; 
import java.util.List; 

import com.subsite.bluetoothio.BluetoothIOPackage; 
import com.oblador.vectoricons.VectorIconsPackage; 

public class MainApplication extends Application implements ReactApplication { 

    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 
    @Override 
    protected boolean getUseDeveloperSupport() { 
     return BuildConfig.DEBUG; 
    } 

    @Override 
    protected List<ReactPackage> getPackages() { 
     return Arrays.<ReactPackage>asList(
      new MainReactPackage(), 
      new BluetoothIOPackage(this), //<- How pass the activity 
             // from ReactApplication ? 
      new VectorIconsPackage() 
    ); 
    } 
    }; 

    @Override 
    public ReactNativeHost getReactNativeHost() { 
     return mReactNativeHost; 
    } 
} 

Trả lời: Bạn KHÔNG chuyển Hoạt động từ MainỨng dụng cho gói.

Bạn gọi getCurrentActivity() từ bên trong ReactContextBaseJavaModule bạn

+0

Đừng bận tâm. Lớp ReactContextBaseJavaModule có phương thức getCurrentActivity(). –

-1

tôi cần phải sửa đổi một module đã lỗi thời (react-android-360-video) và thấy hữu ích ...

này Trong android/app/src/main/java/com/webcdpmobiledemo/MainApplication.java, tôi sử dụng định dạng mới để thêm một gói:

... 
import com.vrvideocomponent.VrVideoViewPackage; 

public class MainApplication extends Application implements ReactApplication { 

    ... 

    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 
     ... 

     @Override 
     protected List<ReactPackage> getPackages() { 
     return Arrays.<ReactPackage>asList(
      new MainReactPackage(), 
      new VrVideoViewPackage() 
     ); 
     } 

     ... 
    }; 

    ... 
} 

android/app/src/main/java/com/webcdpmobiledemo/MainActivity.java là chủ yếu có sản phẩm nào:

package com.yourproject; 

import com.facebook.react.ReactActivity; 

public class MainActivity extends ReactActivity { 

    /** 
    * Returns the name of the main component registered from JavaScript. 
    * This is used to schedule rendering of the component. 
    */ 
    @Override 
    protected String getMainComponentName() { 
     return "YourProject"; 
    } 
} 

Sau đó, tôi sửa đổi các tập tin VrVideoViewPackage, mà cần phải vượt qua reactContext đến VrVideoViewManager nó gọi:

... 

public class VrVideoViewPackage implements ReactPackage { 
    ... 

    @Override 
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { 
     return Arrays.<ViewManager>asList(
       new VrVideoViewManager(reactContext) 
     ); 
    } 

} 

Và cuối cùng, trong VrVideoViewManager hoạt động có thể được truy cập như vậy:

... 

import android.app.Activity; 
import com.facebook.react.uimanager.ThemedReactContext; 
import com.facebook.react.bridge.ReactContext; 

... 

public class VrVideoViewManager extends SimpleViewManager<VrVideoView> { 
    ... 

    public VrVideoViewManager(ReactContext reactContext) { 
     // Do not store mActivity, always getCurrentActivity when needed 
     Activity mActivity = mContext.getCurrentActivity(); 
    } 

    @Override 
    protected VrVideoView createViewInstance(ThemedReactContext reactContext) { 

     // You can also activity from ThemedReactContext 
     Activity mActivity = reactContext.getCurrentActivity(); 

     VrVideoView vrView = new VrVideoView(mActivity); 
     vrView.setEventListener(new ActivityEventListener(vrView)); 
     vrView.pauseVideo(); 
     return new VrVideoView(mActivity); 
    } 

    ... 
} 
+0

Gói Upto là ok, sau đó? tôi có để có được DeviceToken từ Module 'lớp công cộng DeviceModule mở rộng ReactContextBaseJavaModule' một chuỗi giá trị như "PackageReference.ReactOverridemethod.StringValue" từ .js ???? – Ramaraju

+0

@Ramaraju Tôi không chắc tôi hiểu câu hỏi của bạn, bạn có thể thuật lại không? Giải pháp mà tôi cung cấp là trích xuất hoạt động trong lớp ReactPackage và lớp SimpleViewManager. Nếu bạn muốn trích xuất từ ​​lớp ReactContextBaseJavaModule bạn có thể kiểm tra câu trả lời của efkan –

Các vấn đề liên quan