Почему сбой автоматической ссылки в react-native-zip-archive?

#android #react-native #gradle #expo

#Android #react-native #gradle #выставка

Вопрос:

У меня есть проект Expo, к которому я пытаюсь добавить react-native-zip-archive . Я точно следовал документам, но автоматическая ссылка не работает на Android (не пробовал iOS). Я получаю сообщение об ошибке в индексном файле пакета, TypeError: null is not an object (evaluating 'RNZipArchive.unzip') .

Я подозреваю, что в gradle пакета есть что-то, что виновато, но я не знаю достаточно, чтобы это отладить. Здесь что-нибудь не так?

 buildscript {
    repositories {
        jcenter()
        google()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'
    }
}

apply plugin: 'com.android.library'

android {
    compileSdkVersion rootProject.ext.compileSdkVersion
    buildToolsVersion rootProject.ext.buildToolsVersion

    defaultConfig {
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"
    }
    lintOptions {
        abortOnError false
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation "com.facebook.react:react-native: "
    implementation "net.lingala:zip4j:1.3.3"
}
  

Комментарии:

1. я столкнулся с этой проблемой. вы нашли решение?

2. Нет, к сожалению, я сдался.

3. Вы пробовали какие-либо другие модули? Я сталкиваюсь с той же проблемой, и, к сожалению, я не могу сдаться.

Ответ №1:

Я также не смог найти решение для null is not an object ошибки в react-native-zip-archive. В итоге я написал Java-модуль и связал его со своим проектом react-native. Это намного быстрее и проще в использовании.

Сохраните этот файл как ZipModule.java в android / app / src / main / java / com / YOUR PROJECT /

 package com.<YOUR PROJECT>;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import java.util.Map;
import java.util.HashMap;

import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

import java.io.File;
import java.io.IOException;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import android.util.Log;

public class ZipModule extends ReactContextBaseJavaModule {
    ZipModule(ReactApplicationContext context) {
        super(context);
    }

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

    @ReactMethod
    public void unzip(String zipFile, String targetDirectory, Callback cb) {
        
        try {
            ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFile)));

            ZipEntry ze;
            int count;
            
            byte[] buffer = new byte[8192];
            
            while ((ze = zis.getNextEntry()) != null) {
                File file = new File(targetDirectory, ze.getName());
                File dir = ze.isDirectory() ? file : file.getParentFile();
                if (!dir.isDirectory() amp;amp; !dir.mkdirs()) {
                    throw new FileNotFoundException("Failed to ensure directory: "   dir.getAbsolutePath());
                }
                
                if (ze.isDirectory()) {
                    continue;
                }

                FileOutputStream fout = new FileOutputStream(file);
                try {
                    while ((count = zis.read(buffer)) != -1) {
                        fout.write(buffer, 0, count);
                    }
                } finally {
                    fout.close();
                }
            }
            zis.close();
        }
        catch(FileNotFoundException err) {
            cb.invoke(err);
        }
        catch(Exception err) {
            cb.invoke(err);
        }
        finally {
            cb.invoke();
        }
    }
} 
  

Сохраните этот файл как MyAppPackage.java в android / app / src / main / java / com / YOUR PROJECT /

 package com.<YOUR PROJECT>;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

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

public class MyAppPackage implements ReactPackage {

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }

    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();

        modules.add(new ZipModule(reactContext));

        return modules;
    }

}
  

И в вашем MainApplication.java в android / app /src /main / java / com / YOUR PROJECT / добавьте свой MyAppPackage класс

 @Override
protected List<ReactPackage> getPackages() {
   @SuppressWarnings("UnnecessaryLocalVariable")
   List<ReactPackage> packages = new PackageList(this).getPackages();
   // Packages that cannot be autolinked yet can be added manually here
   packages.add(new MyAppPackage());
   return packages;
}
  

И все; ваш собственный модуль извлечения zip готов к использованию. Чтобы вызвать это в вашем JS-коде, попробуйте следующий пример

 import { NativeModules } from "react-native";

/* Note: do not destructure ZipModule from NativeModules. It doesn't work that way */
const ZipModule = NativeModules.ZipModule;

ZipModule.unzip(zipFile, targetDir, (err) => {
   if(err) {
   /* Handle the errors here */
      console.error(err);
      return;
   }
   /* Handle What you want to do after file extraction */
}) 
  

Также не забывайте перестраивать свое приложение ( react-native run-android ) каждый раз, когда вы вносите изменения в класс Java