Jak publikovat Windows 10 aplikaci do Store

Povedlo se mi publikovat mou první aplikaci ve Windows Store 🙂 Jedná se o můj klasický HelloWorld 🙂 https://www.microsoft.com/cs-cz/store/apps/motor-cb/9nblggh4v9ft

Tady jsou mé poznámky a poznatky k celému procesu.

Nejprve je nutné se přihlásit Microsoftím účtem: https://dev.windows.com/cs-cz

V řídícím panelu klikneme na tlačítko Vytvořit novou aplikaci :  (https://dev.windows.com/cs-cz/registration/AccountInfo). Při prvním spuštění toho kroku je nutné vyplnit údaje o autorovi aplikace a zaplatit jednorázový poplatek 365,-Kč (částka se ještě navýší o daň = cca 77,-Kč). Celkem tedy 442Kč. Platbu je možné provést přes kreditní kartu nebo PayPal.

Vytvořenou UWP (Universal Windows Platform) aplikaci a vyexportujeme ji přímo z Visual Studia. Klikneme na projekt pravým tlačítkem a vybereme Store ->Create App Packages … :

store1

store2

Poté je ještě nutné spustit App Certification Kit – jedná se o testy, které se samy vykonají a otestují základní funkčnost aplikace. Po dokončení těchto kroků máme k dispozici soubor s aplikací:

Documents\Visual Studio 2015\Projects\MotorCB\MotorCB\AppPackages\MotorCB_1.1.6.0_x86_x64_arm_bundle.appxupload

Ten nahrajeme na https://developer.microsoft.com/cs-cz/dashboard/overview a doplníme povinné údaje.

store3

A pak už jen čekat 🙂 Mou první aplikaci schválili za necelé 2 dny. Při tomto procesu se opět na aplikaci spouští testy.

Každý další upgrade aplikace je většinou schválen do 24hodin a do dalších 24 hodin se změny projeví ve Windows Store.

store4

Záseky při publikování aplikací

Šipka zpět

Tohle jsem nepochopil, ale programátor si musí ošetřit funkčnost šipky zpět 🙂 Úprava spočívá v přidání těchto řádků:

 namespace MotorCB
 {
     /// <summary>
     /// Provides application-specific behavior to supplement the default Application class.
     /// </summary>
     sealed partial class App : Application
     {
         /// <summary>
         /// Initializes the singleton application object.  This is the first line of authored code
         /// executed, and as such is the logical equivalent of main() or WinMain().
         /// </summary>
         public App()
         {
             Microsoft.ApplicationInsights.WindowsAppInitializer.InitializeAsync(
                 Microsoft.ApplicationInsights.WindowsCollectors.Metadata |
                 Microsoft.ApplicationInsights.WindowsCollectors.Session);
             this.InitializeComponent();
             this.Suspending += OnSuspending;
         }
 
         /// <summary>
         /// Invoked when the application is launched normally by the end user.  Other entry points
         /// will be used such as when the application is launched to open a specific file.
         /// </summary>
         /// <param name="e">Details about the launch request and process.</param>
         protected override void OnLaunched(LaunchActivatedEventArgs e)
         {
 #if DEBUG
             if (System.Diagnostics.Debugger.IsAttached)
             {
                 this.DebugSettings.EnableFrameRateCounter = false;
             }
 #endif
             Frame rootFrame = Window.Current.Content as Frame;
 
             // Do not repeat app initialization when the Window already has content,
             // just ensure that the window is active
             if (rootFrame == null)
             {
                 // Create a Frame to act as the navigation context and navigate to the first page
                 rootFrame = new Frame();
 
                 rootFrame.NavigationFailed += OnNavigationFailed;
+                rootFrame.Navigated += OnNavigated;
 
                 if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
                 {
                     //TODO: Load state from previously suspended application
                 }
 
                 // Place the frame in the current Window
                 Window.Current.Content = rootFrame;
+
+                // Register a handler for BackRequested events and set the
+                // visibility of the Back button
+                SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
+
+                SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
+                    rootFrame.CanGoBack ?
+                    AppViewBackButtonVisibility.Visible :
+                    AppViewBackButtonVisibility.Collapsed;
             }
 
             if (e.PrelaunchActivated == false)
             {
                 if (rootFrame.Content == null)
                 {
                     // When the navigation stack isn't restored navigate to the first page,
                     // configuring the new page by passing required information as a navigation
                     // parameter
                     rootFrame.Navigate(typeof(MainPage), e.Arguments);
                 }
                 // Ensure the current window is active
                 Window.Current.Activate();
             }
         }
 
         /// <summary>
         /// Invoked when Navigation to a certain page fails
         /// </summary>
         /// <param name="sender">The Frame which failed navigation</param>
         /// <param name="e">Details about the navigation failure</param>
         void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
         {
             throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
         }
 
+        private void OnNavigated(object sender, NavigationEventArgs e)
+        {
+            // Each time a navigation event occurs, update the Back button's visibility
+            SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
+                ((Frame)sender).CanGoBack ?
+                AppViewBackButtonVisibility.Visible :
+                AppViewBackButtonVisibility.Collapsed;
+        }
+
         /// <summary>
         /// Invoked when application execution is being suspended.  Application state is saved
         /// without knowing whether the application will be terminated or resumed with the contents
         /// of memory still intact.
         /// </summary>
         /// <param name="sender">The source of the suspend request.</param>
         /// <param name="e">Details about the suspend request.</param>
         private void OnSuspending(object sender, SuspendingEventArgs e)
         {
             var deferral = e.SuspendingOperation.GetDeferral();
             //TODO: Save application state and stop any background activity
             deferral.Complete();
         }
+
+
+        private void OnBackRequested(object sender, BackRequestedEventArgs e)
+        {
+            Frame rootFrame = Window.Current.Content as Frame;
+
+            if (rootFrame.CanGoBack)
+            {
+                e.Handled = true;
+                rootFrame.GoBack();
+            }
+        }
     }
 }

Otevření URL ve webovém prohlížeči

String url = "http://blog.venca-x.cz"
await Launcher.LaunchUriAsync(new Uri(url));

 

Android: layout pro různá zařízení

Pokud si přejete zobrazit různý layout pro telefon, 7″ tablet a 10″ tablet určitě vám pomohou tyto poznámky.

Starý a již nepreferovaný způsob:

  • layout výchozí složka – v té máte základní layout
  • layout-large pro 7″ tablet (funguje pro emulátor Nexus 7)
  • layout-xlarge pro 10″ tablet (funguje pro emulátor Galaxy Tab 10.1)

Nový preferovaný způsob je vybrání layoutu podle hodnoty dp

Jednotka dp (density independent piuxel) vyjadřuje fyzickou velikost displeje. a je definován vztahem:

1dp = 160px/dpi
  • 320dp: typické rozlišení pro telefon (240×320 ldpi, 320×480 mdpi, 480×800 hdpi, atd.).
  • 480dp: phablet – něco mezi telefonem a tabletem (480×800 mdpi).
  • 600dp: 7” tablet (600×1024 mdpi).
  • 720dp: 10” tablet (720×1280 mdpi, 800×1280 mdpi, atd)

Šablony pro zůzně velká zařízení

  • sw600dp = nejmenší rozměr (smallestWidth) 600dp – použije se pokud nejmenší rozměr displeje je alespoň 600dp – bez ohledu na to zda je to šířka nebo výška
  • w600dp = šířka displeje 600dp
  • h600dp = výška displeje 600dp

Příklad: Nexus 6 se má velikost displeje 5,96″ a Quad HD v rozlišení 2560 x 1440 (493 ppi). To odpovídá ~ 730 x 410 dp

Vaše zařízení můžete dohledat na adrese http://www.emirweb.com/ScreenDeviceStatistics.php

Typická zařízení

  • Nexus 7: 1280 x 800 px (961 x 600 dp) / tvdpi / Large screen
  • Nexus 10: 2560 x 1600 px (1280 x 800 dp) / xhdpi / XLarge screen

Pokud tedy chci layout pro Nexus 7, založím ve složce app\src\main\res\layout-w600dp\ požadovaný layout

Pro Nexus 10 založím v app\src\main\res\layout-w720dp\ požadovaný layout

Android – jak změnit barvu Chrome záhlaví

Chrome od verze 39 na telefonech Android dokáže změnit barvu záhlaví prohlížeče a přidat logo. Změnu uděláte velice jednoduchou syntaxí. Kód uvedený níže přidáte do tagu tagu <header>:

<meta name="theme-color" content="#db5945">

Navíc můžete přidat také ikonu v rozumném rozlišení (192 x 192px):

<link rel="icon" sizes="192x192" href="pictures/logo192.png">

Výsledek:

chrome-color-page chrome-color-task

Android jak na služby (services)

Pokud v Androidu vykonáváte větší množství operací, není vhodné tuto práci dělat v hlavním vlákně aplikace. Tuto práci musíte udělat v novém vlákně (AsynsTask) nebo ve službě (services). Dnes si ukážeme jak udělat jednoduchou službu.

Na rozdíl od aktivit běží služby na pozadí a nepotřebují uživatelské rozhraní. Služba běží paralelně s hlavním vláknem. Klasickým příkladem služby je přehrávač hudby na pozadí. Když hudba hraje, uživatel se může přepnout do jiné aplikace a přehrávání hudby se nepřeruší. Klasickým případem je stahování/odesílání dat z internetu, práce s databází, zpracování velkých souborů, přehrávání hudby,…

Služby je nutné registrovat v AndroidManifest.xml

    <application ....>
        <activity android:name=".activity.MainActivity" >
           ...
        </activity>

        <service
            android:name=".service.MyService"
            android:exported="false" >
        </service>

    </application>

Poslední dobou se mi líbí přístup definování volání služby jako statickou metodu přímo v service:

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import my.namespace.Config;

public class MyService extends IntentService {

    private static final String MY_TASK = "my.namespace.action.MY_TASK";
    private static final String MY_PARAM = "myParam";


    public MyService() {
        super("MyService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        if (intent != null) {
            final String action = intent.getAction();
            String myParam = intent.getStringExtra(MY_PARAM);

            if (MY_TASK.equals(action)) {

                //my task hard work
                if (Config.DEBUG) Log.d(Config.TAG, "my task hard work with my param: " + myParam );

            }
        }
    }

    public static void runMyService(Context context, String parameter) {

        if (Config.DEBUG) Log.d(Config.TAG, "runMyService()");

        Intent intent = new Intent(context, MyService.class);
        intent.setAction(MY_TASK);
        intent.putExtra(MY_PARAM, parameter);
        context.startService(intent);

    }

}

Metodou runMyService spustíme službu, která vynutí zavolání metody onHandleIntent kde se podle proměnné action rozhodne jaká z úloh se bude provádět (v budoucnu se předpokládá více činnosti pro službu).

Zavolání služby je pak jednoduché:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (Config.DEBUG) Log.d(Config.TAG, "onCreate()");

        MyService.runMyService(getContext(), "muj parametr");

    }

 

 

WordPress – jak v PHP nastavit cron (wp_cron)

Dnes si ukážeme jak v pluginu pro WordPressu nastavit wp_cron. Cron je script (ve WP světě funkce) který se spustí vždy v požadovanou dobu.

Jediné případné použití je na hostingu, který nepodporuje cron, nebo má omezený počet úloh pro cron. Wp_cron totiž funguje tak, že když přijde návštěvník na web, podívá se zda uplynula doba na spuštění cron úlohy. Pokud doba uplynula spustí cron úlohu a poznamená si čas kdy tato úloha byla naposledy spuštěna aby věděl kdy ji spustit příště.

To je fajn ale má to několik nedostatků:

  • Pokud na Váš web za celý den nepřijde žádný člověk, nevykoná se cron pro hourly četnost ani jednou (normálně by se vykonal 24x)
  • Pokud máte cron úlohu, která se vykonává dlouho, návštěvník který tuto úlohu „spustil“ musí počkat než doběhne aby se mu zobrazila požadovaná stránka

Raději doporučuji spouštět kód klasickým cronem.

Ukázka nejjednoduššího cronu, který se vykoná každou hodinu – odesílá email:

if ( ! wp_next_scheduled( 'my_task_hook' ) ) {
  wp_schedule_event( time(), 'hourly', 'my_task_hook' );
}

add_action( 'my_task_hook', 'my_task_function' );

function my_task_function() {
  wp_mail( 'your@email.com', 'Automatic email', 'Automatic scheduled email from WordPress.');
}

Cron pro WordPress plugin

U pluginu je nejrozumnější cron zapnout při aktivaci pluginu. Nezapomeňte cron opět odebrat při deaktivaci pluginu.

Jak zjistím, že plugin byl aktivován nebo deaktivován?

function activate_plugin_name() {
   //plugin byl aktivovan
}

function deactivate_plugin_name() {
   //plugin byl deaktivovan
}
register_activation_hook( __FILE__, 'activate_plugin_name' );
register_deactivation_hook( __FILE__, 'deactivate_plugin_name' );

Jednoduché, ale stálo mne to dost vlasů 🙂 Finální kód pro plugin:

/**
 * Tento kod se vykona pri aktivaci pluginu
 */
function activate_plugin_name() {
   if( !wp_next_scheduled( 'mycronjob' ) ) {
      wp_schedule_event( time(), 'hourly', 'mycronjob' );
   }
}
/**
 * Tento kod se vykona pri deaktivaci pluginu
 */
function deactivate_plugin_name() {
   wp_clear_scheduled_hook('mycronjob');
}
//hook pro aktivaci a deaktivaci pluginu
register_activation_hook( __FILE__, 'activate_plugin_name' );
register_deactivation_hook( __FILE__, 'deactivate_plugin_name' );

/**
 * Funkce s vykonym kodem pro cron ulohu
 */
function my_repeat_function() {
   file_put_contents( realpath(dirname(__FILE__)) . "/cron.txt", date( "d.m.Y H:i:s" ) . " cron\n", FILE_APPEND);
}

Doufám, že pomůže 🙂

Android aplikace + New Relic

Pro analýzu používání a padání Android aplikací se mi osvědčil New Relic (mimochodem, je super i na server). V základní verzi je zadarmo. Obsahuje základní informace které pro malé aplikace bohatě stačí (v kombinaci New relic + Google play API mi momentálně nechybí žádná funkčnost). Pro mne nejužitečnější je crash list report, kde vidíte všechny pády vaší aplikace včetně mnoha informací (jaké to bylo zařízení, verze Androidu , …), Je naivní si myslet, že když aplikace funguje na mém zařízení, bude fungovat všude… Vždy jsem matně vzpomínal jsem jsem New Relic do aplikace dostal. To co stačí udělat naleznete v tomto videu:

Ať slouží 🙂

Android: GPS souřadnice zařízení

V dnešním článku si ukážeme jak z Android zařízení získat aktuální GPS polohu. K získání polohy použijeme LocationListener.

Oprávnění pro přístup k poloze

Do AndroidManifest.xml přidáme následující oprvnění:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Používáme Android LocationManager

Activita ve které chceme zjistit GPS polohu musíme implementovat rozhraní LocationListener (z package android.location.LocationListener)

public class MainActivity extends Activity implements LocationListener {
    
    private LocationManager locationManager;

kde následně musíme přetížit tyto metody:

    @Override
    public void onLocationChanged(Location location) {
        Log.d("GPS", "Lat: " + location.getLatitude() + "Lon: " + location.getLongitude());
        Toast.makeText(getActivity(), "Lat: " + location.getLatitude() + "Lon: " + location.getLongitude(), Toast.LENGTH_LONG).show();
        locationManager.removeUpdates(this);//stop gps changes, only ONE
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {
        Toast.makeText(getActivity(), "Gps is turned ON", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onProviderDisabled(String provider) {
        Toast.makeText(getActivity(), "Gps is turned OFF", Toast.LENGTH_SHORT).show();
    }

Vynutíme získání polohy:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
 
   locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
   locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2000, 1, this);
}

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 1, this) kde parametry funkce:

provider provider pro zjištění polohy
minTime minimální interval pro aktualizaci polohy (v milisekundách)
minDistance minimální vzdálenost mezi aktualizacemi (v metrech). Pokud nepotřebujeme změnu po metrech, nastavíme na 0 -> tím se bude aktualizovat pouze podle česového intervalu (minTime)
listener listener jehož metoda onLocationChanged(Location) se zavolá s každou změnou

Pokud budeme chtít listener pro zjišťování polohy ukončit, zavoláme:

locationManager.removeUpdates(this);

Všimněte si že první zjištění polohy trvá docela dlouho a zařízení se zahřívá více než obvykle. I baterie ubývá rychleji než obvykle 🙂 Příště si ukážeme šetrnější způsob jak zjišťovat polohu zařízení, který při prvním spuštění rychle vrátí naposledy známou polohu a poté ji zpřesní, nebo jak zjistit, že GPS je vypnuta.

Jak nainstalovat Bower pod Windows

Minule jsme si nainstalovali Grunt a vytvořili package.json

Nyní se rovnou pustíme do instalace Boweru. Bower nainstalujeme globálně abychom ho mohli použít kdekoliv:

npm install -g bower

Také Bower nainstalujeme lokálně aby se přidal do projektu (package.json)

npm install bower --save-dev

Inicializujeme Bower (vytvoří soubor bower.json):

bower init

 

Hledání balíčků

Existují 2 způsoby jak najít balíček pro Bower. Buď přes webový prohlížeč nebo přes příkazovou řádku.

Chcete li vyhledat balíček přes příkazovou řádku, použijte následující příkaz:

bower search <balicek>

Pro vyhledání balíčku obsahující slovo jQuery použijeme příkaz:

bower search jquery

Tento příkaz vrátí spoustu výsledků:

    jquery git://github.com/components/jquery.git
    jquery-ui git://github.com/components/jqueryui
    jquery.cookie git://github.com/carhartl/jquery-cookie.git
    jquery-placeholder git://github.com/mathiasbynens/jquery-placeholder.git
    jquery-file-upload git://github.com/blueimp/jQuery-File-Upload.git
    jasmine-jquery git://github.com/velesin/jasmine-jquery
    jquery.ui git://github.com/jquery/jquery-ui.git
    ...

Každý balíček odkazuje na Git repozitář.

Instalace Balíčků

bower install jquery#1.*.* --save-dev         //last version jquery 1.x.x
bower install nette-forms --save-dev
bower install bootstrap --save-dev
bower install bootstrap-sass-official --save-dev
bower install jquery-smooth-scroll --save-dev
bower install font-awesome --save-dev

Android: Začínáme s Volley

Knihovnu Volley vyvinula společností Google. Slouží pro rychlou a snadnou komunikaci přes internet v systému Android. Dnes si ukážeme jak Volley používám pro stahování dat z internetu. Především stahování dat z REST API.

Do knihovny Volley přispěl svým kódem můj kolega Zdeněk Kořán 🙂

Gradle v Android Studiu

Pro všechny mé projekty pro Android používám Android Studio. Je to ideální volba. Zprovoznění simulátoru a nainstalování SDK (oproti Eclipse) je velice jednoduché a příjemné.

Gradle je nástroj pro automatizaci. Slouží k: build, CI, deployment, generování dokumentace, … Po vytvoření nového projektu v Android Studio je Gradle výchozí nástroj.

Přidání Volley knihovny do projektu v Android Studiu

Vytvořte v Android Studio nový projekt. Otevřete soubor build.gradle do kterého doplníme závislost:

// /app/build.gradle
// ...

dependencies {
  // ...
  compile 'com.mcxiaoke.volley:library:1.0.+'
}

Lepší je načíst poslední verzi knihovny Volley: File -> Project Structure… -> app -> Dependencies -> Add -> Library dependency kde v modálním okně vyhledáme „com.mcxiaoke.volley:library“ kterou přidáte. Hotovo 🙂

Soubor build.gradle pak vypadá takto:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.1"

    defaultConfig {
        applicationId "cz.vencax.beerdroid.beerdroid"
        minSdkVersion 14
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.0.0'
    compile 'com.android.support:support-v4:22.0.0'
    compile 'com.mcxiaoke.volley:library:1.0.+'
}

Použití Volley knihovny

Volley knihovnu již máme naimportovanou. Pojďme ji začít používat k stahování obsahu z internetu. Kdybychom nepoužili Volley museli bychom obsah stahovat v samostatném vlákně přes AsyncTask. S Volley to je jednoduché. Volley pro požadavky ke stažení používá Request Queue. Pro globální frontu požadavků si vytvoříme statickou třídu VolleySingleton.

VolleySingleton.java:

import android.content.Context;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;

public class VolleySingleton {

    private static VolleySingleton mInstance;
    private RequestQueue mRequestQueue;
    private static Context mCtx;

    private VolleySingleton(Context context) {
        mCtx = context;
        mRequestQueue = getRequestQueue();
    }

    public synchronized static VolleySingleton getInstance(Context context) {
        if (mInstance == null) {
            mInstance = new VolleySingleton(context);
        }
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            // getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return mRequestQueue;
    }
}

Přidáme oprávnění pro přístup na internet (<uses-permission android:name=„android.permission.INTERNET“ />):

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cz.vencax.beerdroid.beerdroid" >

    <uses-permission android:name="android.permission.INTERNET" />
    
    <application
       //...
    </application>

</manifest>

 Stažení JSONu přes Volley

Nyní máme vše připraveno a můžeme začít stahovat obsah z internetu přes Volley.

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> volley
        JsonObjectRequest request = new JsonObjectRequest("http://cblunt.github.io/blog-android-volley/response.json", null,
                new Response.Listener<JSONObject>() {

                    @Override
                    public void onResponse(JSONObject response) {
                        Toast.makeText(getApplicationContext(), response.toString(), Toast.LENGTH_SHORT).show();
                    }
                },

                new Response.ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(getApplicationContext(), "EROOR: " + error.toString(), Toast.LENGTH_SHORT).show();
                    }
                }
        );

        VolleySingleton volleySingleton = VolleySingleton.getInstance(getApplicationContext());

        volleySingleton.getRequestQueue().add(request);
        // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< volley
    }

Jak sami vidíte, s knihovnou Volley je stahování zdrojů z internetu velice jednoduché a rychlé. Sám Google ji používá u svých služeb (Google Play, Youtube, …), nemusíte se tudíž bát že Vaši aplikaci zpomalí.

Mne tato knihovna ušetřila spousty vlasů na hlavě 🙂

Na co si dát pozor

U JSONu se rozlišují 2 typy. Pozor na to při requestu.

JSONObject

začíná znakem {

JSONArray

začíná znakem [

První projekt s Apache Wicket

Jeden z nejlepších webových frameworků pro programovací jazyk Java je Apache Wicket. V dnešním článku si ukážeme jak ho rozchodit na Windows.

Maven

Maven je mocný nástroj pro správu projektů. My ho použijeme pro Wicket Quickstart

  1. http://maven.apache.org/download.html
  2. Stáhnout apache-maven-3.3.1-bin.zip
  3. Stažený Maven rozbalíme do: C:\apache-maven-3.3.1
  4. Přidáme proměnné prostředí s názvem MAVEN_HOME s hodnotou C:\apache-maven-3.3.1
  5. Do proměnného prostředí s názvem Path přidáme (na úplný konce, nezapomeňte na středník!):
    ;C:\apache-maven-3.3.1\bin
  6. Restartujeme PC. Maven je nainstalován. Vyzkoušejte jeho správnou funkčnost: Start -> cmd
    mvn -version

    Zobrazí se verze nainstalovaného Mavenu

Instalace Eclipse

Eclipse je nástroj, který je zdarma a vřele ho doporučuji všem začátečníkům.

  1. http://www.eclipse.org/downloads/
  2. Stáhněte Eclipse IDE for Java EE Developers
  3. Stáhne se zip soubor, který stačí rozbalit a rovnou spustit eclipse.exe (neinstaluje se)

Vytvoření Wicket projektu

Na stránce: https://wicket.apache.org/start/quickstart.html naklikáme vlastnosti (můžeme nechat defaultní) a v cmd vykonáme Command line kód:

mvn archetype:generate -DarchetypeGroupId=org.apache.wicket -DarchetypeArtifactId=wicket-archetype-quickstart -DarchetypeVersion=6.19.0 -DgroupId=com.mycompany -DartifactId=myproject -DarchetypeRepository=https://repository.apache.org/ -DinteractiveMode=false

Kód vytvoří nový projekt ve složce myproject

Spuštění Wicket projektu v Eclipse

v příkazové řádce se dostaneme do projektu:

cd myproject

Nyní spusťte příkaz:

mvn eclipse:eclipse

Tím se vytvoří soubory: .project, .settings, a .classpath které vyžaduje Eclipse.

Nyní naimportujeme projekt do Eclipse. V menu vyberte: File->Import->General->Existing Project into Workspace

V levé části Eclipse najedeme na soubor: src/test/java kde nás zajímá soubor Start.java klikneme na něj pravým tlačítkem a vybereme: Debug as… -> Java Application. Ve spodní části eclipse je Console ve které můžete vidět spouštěná webového serveru.

Správnou funkčnost Wicketu otestujete zobrazením adresy: http://localhost:8080 na které vás vítá Apache Wicket