Codename One - нативный код для получения нативных логов Android и iOS - PullRequest
0 голосов
/ 22 мая 2018

ОБНОВЛЕНИЕ ДЛЯ ЧИТАТЕЛЕЙ: код, обсуждаемый здесь, теперь доступен в этой библиотеке Codename One (и также в Менеджере расширений CN1 ...): https://github.com/jsfan3/CN1Libs-NativeLogsReader


Короткий вопрос:

Я написал работающий собственный код Android, чтобы получить собственный журнал устройства во время выполнения моих приложений Codename One.Я использовал функции интерфейса , предоставленные Codename One .Мне нужна помощь для реализации этого интерфейса также для iOS.

Длинный вопрос ...

Прежде всего, я попытался получить собственные журналы (такие какте, что предоставляются Android Studio и XCode) , чтобы попросить помощи, когда я получаю странное поведение в своих приложениях ... потому что стандартных журналов Codename One недостаточно в некоторых случаях (например, у меня возникли проблемы снативные компоненты, такие как использование Google Maps CN1Lib).

Я новичок в Android Studio и у меня проблемы с получением Logcat для моих приложений Codename One, у меня также есть серьезные трудности с использованиемСобственные источники, предоставляемые серверами сборки.Более того, у меня нет Mac, поэтому я не могу использовать XCode.

Мои языковые навыки ограничены Codename One Java 8, я не "говорю" на родной Java для Android и чувствую, что iOSСобственный Objective-C не читается ...

Поэтому, чтобы помочь себе , чтобы обеспечить точные журналы, когда мне нужно подать некоторые проблемы в репозитории Github Codename One *, я попытался написать 1030 *собственный код для получения собственных журналов в строке (с которыми я могу управлять несколькими простыми способами, например отображать его в форме и отправлять самому себе по электронной почте) .

Итак ... Мне удалось реализовать код для Android: он отлично работает.Я тестировал в нескольких версиях Android.

CallNativeCode.java

package ...;

import com.codename1.system.NativeInterface;

/**
 * Native Code interface
 */
public interface CallNativeCode extends NativeInterface {

    public void clearAndRestartLog();
    public String readLog();
    public String getFilePath();

}

CallNativeCodeImpl.java

package ...;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class CallNativeCodeImpl {

    public String getFilePath() {
        return null;
    }

    public void clearAndRestartLog() {
        // https://developer.android.com/studio/command-line/logcat
        try {
            Runtime.getRuntime().exec("logcat -b all -c");
            Runtime.getRuntime().exec("logcat");
        } catch (IOException ex) {
            // logcat non available?
        }
    }

    // original code: https://stackoverflow.com/q/12692103
    public String readLog() {
        try {
            Process process = Runtime.getRuntime().exec("logcat -d");
            BufferedReader bufferedReader = new BufferedReader(
                    new InputStreamReader(process.getInputStream()));

            StringBuilder log = new StringBuilder();
            String line = "";
            while ((line = bufferedReader.readLine()) != null) {
                log.append(line);
                log.append("\n");
            }
            return log.toString();
        } catch (IOException e) {
            return "Log is not available.";
        }
    }

    public boolean isSupported() {
        return true;
    }

}

Itработает так: в init () основного класса приложения Codename One я добавил:

// Test of Native code
        CallNativeCode callNativeCode = NativeLookup.create(CallNativeCode.class);
        if (callNativeCode != null && callNativeCode.isSupported()) {
            Log.p("Native code can be executed");
            callNativeCode.clearAndRestartLog();
            Log.p("Native LOG cleared and restarted");
        } else {
            Log.p("Native code cannot be executed");
        }

, затем, когда я хочу получить собственный журнал приложения, я могу выполнить:

String nativeLog = callNativeCode.readLog();

Таким образом, я получаю тот же вывод из Android Studio Logcat без необходимости использования Android Studio и без необходимости подключения устройства к компьютеру.

Я попытался повторить этофункциональность для iOS ... но у меня проблемы, потому что я не знаю Objective-C.Я попытался перенаправить собственный выходной журнал в файл и затем прочитать этот файл (адаптируя некоторый код, который я нашел, и пытаясь угадать, как он работает) ... но я не уверен, как это сделать, и мой код не 'Компилировать на сервере сборки iOS.

Следующий код - это то, что я пытался сделать.Как это можно исправить?Спасибо

myPackageName_CallNativeCodeImpl.h

#import <Foundation/Foundation.h>

@interface cool_teammate_registration_CallNativeCodeImpl : NSObject {
}

-(NSString*)readLog;
-(NSString*)getFilePath;
-(void)clearAndRestartLog;
-(BOOL)isSupported;
@end

myPackageName_CallNativeCodeImpl.m

#import "myPackageName_CallNativeCodeImpl.h"

@implementation myPackageName_CallNativeCodeImpl

-(NSString*)getFilePath{
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    NSString* documentsDirectory = [paths objectAtIndex:0];
    NSString* fileName =[NSString stringWithFormat:@"%@.log",[NSDate date]];
    NSString* logFilePath = [documentsDirectory stringByAppendingPathComponent:fileName];
    return logFilePath;
}

-(NSString)readLog{
    NSString* logFilePath = [self getFilePath];
    NSString* content = [NSString stringWithContentsOfFile:logFilePath encoding:NSUTF8StringEncoding error:nil];
    return content;
}

-(void)clearAndRestartLog{
    // /7521638/iphone-kak-chitat-zhurnaly-prilozhenii-s-ustroistva
    NSString* logFilePath = [self getFilePath];
    freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
}

-(BOOL)isSupported{
    return YES;
}

@end

1 Ответ

0 голосов
/ 22 мая 2018

В моем коде iOS произошла ошибка опечатки (NSString вместо NSStrings*).

В этом посте я нашел полезную информацию: Записать ошибки iOS в файл .Я использовал эту информацию для небольшой оптимизации кода.

Наконец, это мой рабочий код (успешно протестирован на iOS 8, iOS 9, iOS 10, iOS 11).Таким образом я могу получить журнал консоли без необходимости подключения устройства к Mac с установленным XCode:)

myPackageName_CallNativeCodeImpl.m

#import "myPackageName_CallNativeCodeImpl.h"

@implementation myPackageName_CallNativeCodeImpl

// Useful information:
// Log iOS Errors to File
// https://www.progressconcepts.com/blog/log-ios-errors-file/

-(NSString*)getFilePath{
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    NSString* documentsDirectory = [paths objectAtIndex:0];
    NSString* fileName = @"device.log";
    NSString* logFilePath = [documentsDirectory stringByAppendingPathComponent:fileName];
    return logFilePath;
}

-(NSString*)readLog{
    NSString* logFilePath = [self getFilePath];
    NSString* content = [NSString stringWithContentsOfFile:logFilePath encoding:NSUTF8StringEncoding error:nil];
    return content;
}

-(void)clearAndRestartLog{
    NSError *error = nil;
    NSString* logFilePath = [self getFilePath];
    [[NSFileManager defaultManager] removeItemAtPath:logFilePath error:&error];

    // wrap the code to check if the debugger was attached, and only write to the file when it wasn’t
    if (!isatty(STDERR_FILENO)) { 
        freopen([logFilePath cStringUsingEncoding:NSUTF8StringEncoding],"a+",stdout);
        freopen([logFilePath cStringUsingEncoding:NSUTF8StringEncoding],"a+",stderr);
    }
}

-(BOOL)isSupported{
    return YES;
}

@end
...