Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating Custom UI component for android on React Native fails. App crashes

Since Facebook Login Button is available natively, I wanted a React Native wrapper component for Android. So, I tried writing it. But the app crashes even before the start. My github repository is: https://github.com/lalith26/react-native-fb-login-android

I have done the following:

  1. I created the Manager for the LoginButton facebook widget:

https://github.com/lalith26/react-native-fb-login-android/blob/master/android/app/src/main/java/com/fbloginbutton2/FBLoginButtonManager.java

  1. I created a ReactPackage extending MainReactPackage:

https://github.com/lalith26/react-native-fb-login-android/blob/master/android/app/src/main/java/com/fbloginbutton2/FBLoginButtonReactPackage.java

  1. I added the new ReactPackage in MainActivity:

https://github.com/lalith26/react-native-fb-login-android/blob/master/android/app/src/main/java/com/fbloginbutton2/MainActivity.java#L29

  1. I included the gradle dependency for facebook login sdk

https://github.com/lalith26/react-native-fb-login-android/blob/master/android/app/build.gradle#L28

  1. I made the JS component wrapping the Native Component:

https://github.com/lalith26/react-native-fb-login-android/blob/master/fblogin.js

  1. Finally I used the JS component:

https://github.com/lalith26/react-native-fb-login-android/blob/master/index.android.js#L21

I read through the web and found that propTypes are mandatory to be passed. I tried that too. But the app crashes on start itself. I am not able to see any logs. So, I am not able to find the actual reason for the issue. I tried the same set of steps for a button and it worked fine.

Is there something I am simply doing wrong. Please help..

I got access to the logs of the emulator through logcat. It shows:

E/AndroidRuntime( 2550): Process: com.fbloginbutton2, PID: 2550 E/AndroidRuntime( 2550): java.lang.ExceptionInInitializerError E/AndroidRuntime( 2550): at com.fbloginbutton2.FBLoginButtonManager.createViewInstance(FBLoginButtonManager.java:29) E/AndroidRuntime( 2550): at com.fbloginbutton2.FBLoginButtonManager.createViewInstance(FBLoginButtonManager.java:15) E/AndroidRuntime( 2550): at com.facebook.react.uimanager.ViewManager.createView(ViewManager.java:41) E/AndroidRuntime( 2550): at com.facebook.react.uimanager.NativeViewHierarchyManager.createView(NativeViewHierarchyManager.java:172) E/AndroidRuntime( 2550): at com.facebook.react.uimanager.UIViewOperationQueue$CreateViewOperation.execute(UIViewOperationQueue.java:137) E/AndroidRuntime( 2550): at com.facebook.react.uimanager.UIViewOperationQueue$1.run(UIViewOperationQueue.java:574) E/AndroidRuntime( 2550): at com.facebook.react.uimanager.UIViewOperationQueue$DispatchUIFrameCallback.doFrameGuarded(UIViewOperationQueue.java:622) E/AndroidRuntime( 2550): at com.facebook.react.uimanager.GuardedChoreographerFrameCallback.doFrame(GuardedChoreographerFrameCallback.java:32) E/AndroidRuntime( 2550): at com.facebook.react.uimanager.ReactChoreographer$ReactChoreographerDispatcher.doFrame(ReactChoreographer.java:114) E/AndroidRuntime( 2550): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:765) E/AndroidRuntime( 2550): at android.view.Choreographer.doCallbacks(Choreographer.java:580) E/AndroidRuntime( 2550): at android.view.Choreographer.doFrame(Choreographer.java:549) E/AndroidRuntime( 2550): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) E/AndroidRuntime( 2550): at android.os.Handler.handleCallback(Handler.java:739) E/AndroidRuntime( 2550): at android.os.Handler.dispatchMessage(Handler.java:95) E/AndroidRuntime( 2550): at android.os.Looper.loop(Looper.java:135) E/AndroidRuntime( 2550): at android.app.ActivityThread.main(ActivityThread.java:5221) E/AndroidRuntime( 2550): at java.lang.reflect.Method.invoke(Native Method) E/AndroidRuntime( 2550): at java.lang.reflect.Method.invoke(Method.java:372) E/AndroidRuntime( 2550): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) E/AndroidRuntime( 2550): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) E/AndroidRuntime( 2550): Caused by: null E/AndroidRuntime( 2550): at com.facebook.internal.Validate.sdkInitialized(Validate.java:99) E/AndroidRuntime( 2550): at com.facebook.FacebookSdk.getCallbackRequestCodeOffset(FacebookSdk.java:735) E/AndroidRuntime( 2550): at com.facebook.internal.CallbackManagerImpl$RequestCodeOffset.toRequestCode(CallbackManagerImpl.java:109) E/AndroidRuntime( 2550): at com.facebook.login.widget.LoginButton.(LoginButton.java:58) E/AndroidRuntime( 2550): ... 21 more W/ActivityManager( 1327):
Force finishing activity com.fbloginbutton2/.MainActivity E/EGL_emulation( 1373): tid 1373: eglCreateSyncKHR(1181): error 0x3004 (EGL_BAD_ATTRIBUTE)

like image 353
brlalithkumar Avatar asked Sep 28 '15 18:09

brlalithkumar


1 Answers

I found it very difficult to find a simple example or documentation on the issue, so here is an example of my code, extending KenBurnsView (https://github.com/flavioarfaria/KenBurnsView), I hope this example is simple and helpful:

KenBurnsViewManager.Java:

import com.flaviofaria.kenburnsview.KenBurnsView;

import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ReactProp;

import java.io.InputStream;

import android.graphics.drawable.Drawable;
import android.util.Log;

public class KenBurnsViewManager extends SimpleViewManager<KenBurnsView> {

  public static final String REACT_CLASS = "KenBurnsView";
  private ThemedReactContext ctx;

  @Override
  public String getName() {
    return REACT_CLASS;
  }

  @Override
  protected KenBurnsView createViewInstance(ThemedReactContext context) {
    ctx = context;
    return new KenBurnsView(context);
  }

  @ReactProp(name = "source")
  public void setSource(KenBurnsView view, String source) {
    try {
      InputStream ims = ctx.getAssets().open("images/" + source);
      Drawable d = Drawable.createFromStream(ims, null);
      view.setImageDrawable(d);
    } catch (Exception ex) {
      Log.e("KenBurnsView", "setSource", ex);
    }
  }
}

KenBurnsViewPackage.Java:

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.Collections;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;

public class KenBurnsViewPackage implements ReactPackage {
    @Override
    public List<NativeModule> createNativeModules(
        ReactApplicationContext reactContext) {

        List<NativeModule> modules = new ArrayList<>();

        return modules;
    }

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

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

update MainActivity.Java:

mReactInstanceManager = ReactInstanceManager.builder()
                .setApplication(getApplication())
                .setBundleAssetName("index.android.bundle")
                .setJSMainModuleName("index.android")
                .addPackage(new MainReactPackage())
                .addPackage(new KenBurnsViewPackage()) // <- add package
                .setUseDeveloperSupport(BuildConfig.DEBUG)
                .setInitialLifecycleState(LifecycleState.RESUMED)
                .build();

Update android/app/build.gradle:

dependencies {
    compile fileTree(dir: "libs", include: ["*.jar"])
    compile "com.android.support:appcompat-v7:23.0.1"
    compile "com.facebook.react:react-native:0.16.+"
    compile "com.flaviofaria:kenburnsview:1.0.6"
}

KenBurnsView.js:

var { requireNativeComponent, PropTypes, View } = require('react-native');

var iface = {
  propTypes: {
    ...View.propTypes,
    source: PropTypes.string,
  },
};

module.exports = requireNativeComponent('KenBurnsView', iface);

That's it, now you can add the new custom KenBurnsView component, for example:

var KenBurnsView = require('./KenBurnsView');
.
.
.
<KenBurnsView source={'image.jpg'} style={{width:null, height: 300}}/>
like image 77
david72 Avatar answered Oct 23 '22 01:10

david72