Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Pisanie aplikacji na Androida - instalacja i konfiguracja środowiska Visual C++

Ostatnio zmodyfikowano 2016-02-23 21:41
Autor Wiadomość
DejaVu
Temat założony przez niniejszego użytkownika
» 2016-02-08 21:06:01
Najprostsza aplikacja, która powinna się skompilować i uruchomić (i nie crashować).

main.cpp:
C/C++
#include <android/native_activity.h>

void ANativeActivity_onCreate( ANativeActivity * activity, void * savedState, size_t savedStateSize )
{
}

AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="pl.ddt.naukaSFML" android:versionCode="1" android:versionName="1.0">
  <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="19" />
  <application android:label="@string/app_name" android:hasCode="False">
    <activity android:name="android.app.NativeActivity" android:label="@string/app_name" android:configChanges="orientation|keyboardHidden|screenSize">
      <meta-data android:name="android.app.lib_name" android:value="Android4" />
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
  </application>
</manifest>

/edit:
Jakby komuś się crashowała pusta aplikacja to:

      <meta-data android:name="android.app.lib_name" android:value="Android4" />
Nazwa podana w android:value musi być taka sama jak nazwa generowanego pliku wyjściowego. Czyli jeżeli plik wyjściowy ma nazwę Android4.apk, a android:value będzie miało wartość inną niż Android4 to aplikacja będzie się crashowała...
P-144614
DejaVu
Temat założony przez niniejszego użytkownika
» 2016-02-10 21:19:40
Jeżeli chcesz linkować bibliotekę SFML-activity statycznie to koniecznie musisz w opcjach linkera dopisać:
-e ANativeActivity_onCreate
Czyli:
  • Prawy klawisz na projekcie, który jest aplikacją, otwórz Properties
  • Wybierz na drzewku: Configuration Properties/Linker/Command Line
  • W polu "Additional Options" dopisz wyżej wspomniany parametr
Jeżeli tego nie zrobisz, to kompilator wytnie symbol tej funkcji i w konsekwencji aplikacja będzie się crashowała (bo plik wynikowy nie będzie zawierał funkcji wejścia).
P-144717
DejaVu
Temat założony przez niniejszego użytkownika
» 2016-02-13 12:05:04
Co do SFML-a i Androida:
- sprawdziłem, że da się skompilować statycznie biblioteki Activity, Main, System, Window, Graphics.
- nie udało się uruchomić najprostszej aplikacji SFML, która by działała.

Poniższa aplikacja na emulatorze Androida nie odpowiada ani nie zmienia koloru tła.

C/C++
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>

int main( int argc, char * argv[] )
{
    sf::RenderWindow window( sf::VideoMode::getDesktopMode(), "nazwa" );
    sf::View view = window.getDefaultView();
    while( window.isOpen() )
    {
        sf::Event event;
        while( window.pollEvent( event ) )
        {
            if( event.type == sf::Event::Closed )
            {
                window.close();
            }
           
            if( event.type == sf::Event::Resized )
            {
                view.setSize( event.size.width, event.size.height );
                view.setCenter( event.size.width / 2, event.size.height / 2 );
                window.setView( view );
            }
        }
       
        if( sf::Touch::isDown( 0 ) )
             window.close();
       
        window.clear( sf::Color::Red );
        window.display();
    }
    return 0;
}

Pusta aplikacja również się zawiesza:
C/C++
int main( int argc, char * argv[] )
{
    return 0;
}
Powyższy kod powinien pokazać okno aplikacji i natychmiast je zamknąć, tymczasem jest blackscreen.

C/C++
void * main( ActivityStates * states )
{
    // Initialize the thread before giving the hand
    initializeMain( states );
   
    sleep( seconds( 0.5 ) );
    ::main( 0, NULL );
   
    // Terminate properly the main thread and wait until it's done
    terminateMain( states );
   
    {
        Lock lock( states->mutex );
       
        states->terminated = true;
    }
   
    return NULL;
}
Mając na uwadze powyższy fragment kodu SFML, teoretycznie zakończenie funkcji main powinno skutkować zakończeniem aplikacji, a tak się nie dzieje, więc coś musi być nakopane albo z moimi pakietami albo z implementacją pliku MainAndroid.cpp w SFML.

/edit:
A jednak działa :D Jak robiłem eksperymenty to wstawiłem return; na początku funkcji ANativeActivity_onCreate :)
P-144804
DejaVu
Temat założony przez niniejszego użytkownika
» 2016-02-13 12:46:46
Jest jeszcze problem z kończeniem pracy aplikacji:

https://developer.nvidia.com​/fixing-common-android-lifecycle-issues-games
http://stackoverflow.com​/questions/7679097​/how-to-terminate-android-ndk-native-activity-application-programatically
http://www.ikerhurtado.com​/android-ndk-native-activity-app-glue-lib-lifecycle-threads

/edit:
Kolejny problem z SFML-em na Androidzie... mam białe sprajty zamiast tekstur.
Zobaczymy jaką diagnozę wystawią: http://en.sfml-dev.org/forums​/index.php?topic=19798.0

/edit:
Problem rozwiązany poprzez włączenie "Use host GPU" na emulatorze.
P-144808
DejaVu
Temat założony przez niniejszego użytkownika
» 2016-02-22 22:03:31
Ciekawostka :) Jest taki plik jak: Nvidia.AndroidBuild.targets. Fragmenty pliku wyglądają tak:
  <Target Name="AntBuild" DependsOnTargets="BuildLibrariesToPackage" Condition="'$(SkipPackaging)' != 'true'">
    <PropertyGroup>
      <AntBuild_MinimalRebuildFromTracking Condition="'$(BuildType)' != 'Build' or '$(ForceRebuild)' == 'true'">false</AntBuild_MinimalRebuildFromTracking>
      <AntBuild_MinimalRebuildFromTracking Condition="'$(AntBuild_MinimalRebuildFromTracking)' == ''">true</AntBuild_MinimalRebuildFromTracking>
      <AntBuild_IsNdkBuildProject Condition="'$(ConfigurationType)' == 'Utility'">true</AntBuild_IsNdkBuildProject>
      <AntBuild_IsNdkBuildProject Condition="'$(AntBuild_IsNdkBuildProject)' == ''">false</AntBuild_IsNdkBuildProject>
      <FilteredAntBuild Condition="'%(AntBuild.Dummy)' != 'true'">@(AntBuild)</FilteredAntBuild>
      <AntBuildSkippedExecution>true</AntBuildSkippedExecution>
      <IsFastDeployEnabled>false</IsFastDeployEnabled>
      <IsFastDeployEnabled Condition="'$(FastDeploy)' == 'true' or '$(FastDeploy)' == 'Default'">true</IsFastDeployEnabled>
    </PropertyGroup>
    <AntBuild Condition="'%(AntBuild.SkipAntStep)' != 'true' and '$(AndroidBuildSystem)' == 'AntBuild'"
        Configuration                  ="$(Configuration)"
        OutputDir                      ="$(IntermediateDirectoryFullPath)"


(...)

  <Target Name="AntClean">
    <PropertyGroup>
      <AntBuildFullPath>$([System.IO.Path]::Combine($(ProjectDir), %(AntBuild.AntBuildPath)))</AntBuildFullPath>
      <AndroidManifestFullPath>$([System.IO.Path]::Combine($(AntBuildFullPath), %(AntBuild.AndroidManifestLocation)))</AndroidManifestFullPath>
      <IntermediateDirectoryFullPath>$([System.IO.Path]::Combine($(ProjectDir), $(IntDir)))</IntermediateDirectoryFullPath>
      <GradleBuildFullPath>$([System.IO.Path]::Combine($(IntermediateDirectoryFullPath), build))</GradleBuildFullPath>
    </PropertyGroup>

    <Message Text="Performing clean..." />

    <AntClean Condition="'$(AndroidBuildSystem)' == 'AntBuild'"
      SdkRootPath                 ="$(SdkRootPath)"
      JdkRootPath                 ="$(JdkRootPath)"
      ToolRootPath                ="$(AntRootPath)"
      AntBuildPath                ="$(AntBuildFullPath)"
      AndroidManifestLocation     ="$(AndroidManifestFullPath)"
      OutputDir                   ="'$(IntermediateDirectoryFullPath)'">
    </AntClean>

Przez to, że ścieżka w OutputDir nie jest ani w apostrofach ani w cudzysłowiu - nie da się kompilować projektów, które mają w ścieżce spację.

Ciekawostka nr 2:
Po dodaniu apostrofów w OutputDir dla AntClean - czyszczenie projektu działa poprawnie.

Ciekawostka nr 3:
Ten sam trick jednak nie działa przy kompilacji projektów, ponieważ dostajemy błąd:
Error 29 error MSB4018: The "AntBuild" task failed unexpectedly.
System.NotSupportedException: The given path's format is not supported.
   at System.Security.Util.StringExpressionSet.CanonicalizePath(String path, Boolean needFullPath)
   at System.Security.Util.StringExpressionSet.CreateListFromExpressions(String[] str, Boolean needFullPath)
   at System.Security.Permissions.FileIOPermission.AddPathList(FileIOPermissionAccess access, AccessControlActions control, String[] pathListOrig, Boolean checkForDuplicates, Boolean needFullPath, Boolean copyPathList)
   at System.Security.Permissions.FileIOPermission..ctor(FileIOPermissionAccess access, String[] pathList, Boolean checkForDuplicates, Boolean needFullPath)
   at System.IO.Directory.InternalCreateDirectoryHelper(String path, Boolean checkHost)
   at System.IO.Directory.CreateDirectory(String path)
   at Nvidia.PentaK.Build.Tasks.Android.AndroidBuildBase`1.ExecuteTool(String pathToTool, String responseFileCommands, String commandLineCommands)
   at Nvidia.PentaK.Build.Tasks.Android.AntBuild.ExecuteTool(String pathToTool, String responseFileCommands, String commandLineCommands)
   at Nvidia.PentaK.Build.MSBuildInterop.TrackedToolTask.Nvidia.PentaK.Build.MSBuildInterop.ITrackedToolTask.ExecuteTool(String pathToTool, String responseFileCommands, String commandLineCommands)
   at Nvidia.PentaK.Build.MSBuildInterop.Impl.TrackedToolTaskWrapper`1.ExecuteTool(String pathToTool, String responseFileCommands, String commandLineCommands)
   at Microsoft.Build.Utilities.ToolTask.Execute()
   at Microsoft.Build.CPPTasks.TrackedVCToolTask.Execute()
   at Nvidia.PentaK.Build.MSBuildInterop.ToolTaskBase`2.Execute()
   at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
   at Microsoft.Build.BackEnd.TaskBuilder.<ExecuteInstantiatedTask>d__20.MoveNext() C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\v110\Platforms\Tegra-Android\Nvidia.AndroidBuild.targets 254 5 pgMobileSFML-vc11

Poczytałem sobie również kilka tematów z forum NVIDIA i... polityką tej firmy jest 'nie wspieramy spacji w ścieżkach' :) Żałosne.
https://devtalk.nvidia.com​/default/topic/742458​/new-project-help/

Dodam jeszcze, że narzędzia odpowiedzialne za kompilację projektu wspierają poprawnie cudzysłowy.

Czyli, ręczne odpalenie poprawnego polecenia zadziała tj.
D:\jakis katalog\_tmp_\vc11-other[android] Debug (x86)\pgMobileSFML-vc11>C:\Android-DevPack\NVPACK\apache-ant-1.8.2\bin\ant.bat debug -f "D:\jakis katalog\solutions\..\_tmp_\vc11-other[android] Debug (x86)\pgMobileSFML-vc11\nsight_tegra_build.xml" -listener org.apache.tools.ant.XmlLogger
Natomiast polecenie generowane nie zadziała, ponieważ będzie wyglądało tak:
D:\jakis katalog\_tmp_\vc11-other[android] Debug (x86)\pgMobileSFML-vc11>C:\Android-DevPack\NVPACK\apache-ant-1.8.2\bin\ant.bat debug -f D:\jakis katalog\solutions\..\_tmp_\vc11-other[android] Debug (x86)\pgMobileSFML-vc11\nsight_tegra_build.xml -listener org.apache.tools.ant.XmlLogger

Żal :)
P-145191
DejaVu
Temat założony przez niniejszego użytkownika
» 2016-02-23 21:41:13

Workaround na brak obsługi spacji w ścieżkach (Nvidia.PentaK.Build.Tasks.dll)

Jeżeli ktoś będzie chciał obejść buga przy kompilacji projektu, gdy w ścieżce występują spacje to:
1. Zmień nazwę pliku (...)NVPACK\apache-ant-1.8.2\bin\ant.bat na ant-original.bat
2. Utwórz nowy skrypt o nazwie ant.bat i wklej treść:
@echo off
appNvidiaPentakBuildWorkaround-vc11.exe %*
3. Skompiluj sobie poniższy kod:
C/C++
#include <string>
#include <cstdio>

int main( int _argc, char ** _argv )
{
    std::string sExtraSpace = "";
    std::string sCommand;
    for( int i = 1; i < _argc; ++i )
    {
        std::string sParam = _argv[ i ];
        if( sParam == "-f" )
        {
            sCommand += sExtraSpace.c_str();
            sCommand += sParam.c_str();
            sCommand += " \"";
            sExtraSpace.clear();
        } else
        if( sParam == "-listener" )
        {
            sCommand += "\" ";
            sCommand += sParam.c_str();
        } else
        {
            sCommand += sExtraSpace.c_str();
            sCommand += sParam.c_str();
            sExtraSpace = " ";
        } //else
    } //for
    sCommand = "ant-original.bat " + sCommand;
    printf( "[EXECUTING] %s\n", sCommand.c_str() );
    return system( sCommand.c_str() );
}
4. Aplikację skompilowaną z pkt 3. wgraj do tego samego katalogu, w którym modyfikowałeś skrypt ant.bat. Skompilowana aplikacja powinna się nazywać appNvidiaPentakBuildWorkaround-vc11.exe (jeżeli chcesz mieć inną nazwę to musisz poprawić nazwę aplikacji uruchamianą w skrypcie ant.bat.

Od tej pory kompilacja działa poprawnie z poziomu Visual Studio :)
P-145233
1 « 2 »
Poprzednia strona Strona 2 z 2