This commit is contained in:
unknown
2020-08-11 17:26:24 +08:00
18 changed files with 88 additions and 283 deletions

2
.idea/misc.xml generated
View File

@@ -4,7 +4,7 @@
<asm skipDebug="false" skipFrames="false" skipCode="false" expandFrames="false" /> <asm skipDebug="false" skipFrames="false" skipCode="false" expandFrames="false" />
<groovy codeStyle="LEGACY" /> <groovy codeStyle="LEGACY" />
</component> </component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" /> <output url="file://$PROJECT_DIR$/build/classes" />
</component> </component>
</project> </project>

View File

@@ -1,26 +0,0 @@
package com.mogo.base.services.apk;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith( AndroidJUnit4.class )
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals( "com.mogo.base.services.apk.test", appContext.getPackageName() );
}
}

View File

@@ -1,17 +0,0 @@
package com.mogo.base.services.apk;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals( 4, 2 + 2 );
}
}

View File

@@ -26,6 +26,7 @@ import java.util.Set;
public class ALocationClient implements IMogoLocationClient { public class ALocationClient implements IMogoLocationClient {
private static final String TAG = "LocationClient"; private static final String TAG = "LocationClient";
private final Context mContext;
private Set< IMogoLocationListener > sListeners = new HashSet<>( 10 ); private Set< IMogoLocationListener > sListeners = new HashSet<>( 10 );
private MogoLocation mLastLocation; private MogoLocation mLastLocation;
@@ -34,12 +35,7 @@ public class ALocationClient implements IMogoLocationClient {
private boolean mIsDestroyed = false; private boolean mIsDestroyed = false;
public ALocationClient( Context context ) { public ALocationClient( Context context ) {
mClient = new AMapLocationClient( context ); mContext = context;
mClient.setLocationListener( mListener );
mLastLocation = ObjectUtils.fromAMap( mClient.getLastKnownLocation() );
if ( mLastLocation == null ) {
mLastLocation = new MogoLocation();
}
} }
private AMapLocationClient mClient; private AMapLocationClient mClient;
@@ -51,11 +47,12 @@ public class ALocationClient implements IMogoLocationClient {
@Override @Override
public void start( long interval ) { public void start( long interval ) {
if ( mIsDestroyed ) { if ( mClient == null ) {
destroyWarming(); mClient = new AMapLocationClient( mContext );
return; mClient.setLocationListener( mListener );
mLastLocation = ObjectUtils.fromAMap( mClient.getLastKnownLocation() );
} }
if ( mClient != null ) { if ( !mClient.isStarted() ) {
AMapLocationClientOption option = new AMapLocationClientOption(); AMapLocationClientOption option = new AMapLocationClientOption();
option.setLocationMode( AMapLocationClientOption.AMapLocationMode.Hight_Accuracy ); option.setLocationMode( AMapLocationClientOption.AMapLocationMode.Hight_Accuracy );
option.setNeedAddress( true ); option.setNeedAddress( true );
@@ -109,6 +106,9 @@ public class ALocationClient implements IMogoLocationClient {
destroyWarming(); destroyWarming();
return null; return null;
} }
if ( mLastLocation == null ) {
mLastLocation = new MogoLocation();
}
return mLastLocation; return mLastLocation;
} }
@@ -140,7 +140,7 @@ public class ALocationClient implements IMogoLocationClient {
aMapLocation.getLongitude() == 0.0D ) { aMapLocation.getLongitude() == 0.0D ) {
return; return;
} }
Trace.beginSection("timer.onLocationChanged"); Trace.beginSection( "timer.onLocationChanged" );
mLastLocation = ObjectUtils.fromAMap( aMapLocation ); mLastLocation = ObjectUtils.fromAMap( aMapLocation );
synchronized ( sListeners ) { synchronized ( sListeners ) {
Iterator< IMogoLocationListener > listenerIterator = sListeners.iterator(); Iterator< IMogoLocationListener > listenerIterator = sListeners.iterator();

View File

@@ -1,24 +0,0 @@
package com.mogo.module.authorize
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.mogo.module.authorize.test", appContext.packageName)
}
}

View File

@@ -1,17 +0,0 @@
package com.mogo.module.authorize
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View File

@@ -1,24 +0,0 @@
package com.zhidao.mogo.module.event.panel
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.zhidao.mogo.module.event.panel.test", appContext.packageName)
}
}

View File

@@ -1,17 +0,0 @@
package com.zhidao.mogo.module.event.panel
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View File

@@ -368,6 +368,7 @@ public class EntranceFragment extends MvpFragment<EntranceView, EntrancePresente
public void onDestroyView() { public void onDestroyView() {
super.onDestroyView(); super.onDestroyView();
isClickShare = false; isClickShare = false;
TopViewAnimHelper.getInstance().removeAllView();
} }
@Override @Override

View File

@@ -1,24 +0,0 @@
package com.zhidao.mogo.module.left.panel
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.zhidao.mogo.module.left.panel.test", appContext.packageName)
}
}

View File

@@ -1,17 +0,0 @@
package com.zhidao.mogo.module.left.panel
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View File

@@ -112,7 +112,6 @@ public class MapPresenter extends Presenter< MapView > implements
} else if ( type == 1 ) { } else if ( type == 1 ) {
zoomMap( opera_type == 0 ); zoomMap( opera_type == 0 );
} else if ( type == 2 ) { } else if ( type == 2 ) {
// mMogoIntentManager.invoke( AUTONAVI_STANDARD_BROADCAST_RECV, intent );
onChangeCameraMode( opera_type ); onChangeCameraMode( opera_type );
} }
} else if ( key_type == 10048 ) { } else if ( key_type == 10048 ) {
@@ -157,6 +156,7 @@ public class MapPresenter extends Presenter< MapView > implements
mLauncher.backToLauncher( getContext() ); mLauncher.backToLauncher( getContext() );
} }
}, 500L ); }, 500L );
mMogoIntentManager.invoke( AUTONAVI_STANDARD_BROADCAST_RECV, intent );
return; return;
} }
onStopNaviInternal(); onStopNaviInternal();
@@ -183,6 +183,7 @@ public class MapPresenter extends Presenter< MapView > implements
mMogoMapService.getNavi( getContext() ).reCalculateRoute( config ); mMogoMapService.getNavi( getContext() ).reCalculateRoute( config );
} }
mMogoIntentManager.invoke( AUTONAVI_STANDARD_BROADCAST_RECV, intent );
} }
}; };

View File

@@ -2,57 +2,22 @@ package com.mogo.module.service;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import com.alibaba.android.arouter.facade.annotation.Route; import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.mogo.commons.AbsMogoApplication; import com.mogo.commons.AbsMogoApplication;
import com.mogo.map.MogoLatLng;
import com.mogo.map.listener.IMogoMapListener; import com.mogo.map.listener.IMogoMapListener;
import com.mogo.map.location.IMogoLocationListener; import com.mogo.map.location.IMogoLocationListener;
import com.mogo.map.location.MogoLocation;
import com.mogo.map.marker.IMogoMarkerClickListener; import com.mogo.map.marker.IMogoMarkerClickListener;
import com.mogo.map.marker.IMogoMarkerManager;
import com.mogo.map.model.MogoPoi;
import com.mogo.map.navi.IMogoNaviListener; import com.mogo.map.navi.IMogoNaviListener;
import com.mogo.map.navi.MogoNaviInfo;
import com.mogo.map.navi.MogoTraffic;
import com.mogo.map.uicontroller.EnumMapUI;
import com.mogo.map.uicontroller.IMogoMapUIController;
import com.mogo.module.common.MogoModule;
import com.mogo.module.common.MogoModulePaths;
import com.mogo.module.service.network.RefreshCallback;
import com.mogo.module.service.network.RefreshModel;
import com.mogo.module.service.receiver.MogoReceiver;
import com.mogo.module.service.refresh.AutoRefreshStrategy;
import com.mogo.module.service.refresh.CustomRefreshStrategy;
import com.mogo.service.MogoServicePaths;
import com.mogo.service.intent.IMogoIntentListener;
import com.mogo.service.intent.IMogoIntentManager;
import com.mogo.service.map.IMogoMapService;
import com.mogo.service.module.IMogoModuleLifecycle; import com.mogo.service.module.IMogoModuleLifecycle;
import com.mogo.service.module.IMogoModuleProvider; import com.mogo.service.module.IMogoModuleProvider;
import com.mogo.service.module.IMogoRegisterCenter;
import com.mogo.service.module.ModuleType; import com.mogo.service.module.ModuleType;
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
import com.mogo.service.statusmanager.IMogoStatusManager;
import com.mogo.service.statusmanager.StatusDescriptor;
import com.mogo.utils.UiThreadHandler; import com.mogo.utils.UiThreadHandler;
import com.mogo.utils.logger.Logger;
import java.util.Iterator;
import java.util.List;
/** /**
* @author congtaowang * @author congtaowang
@@ -128,6 +93,7 @@ public class MogoServiceProvider implements IMogoModuleProvider {
@Override @Override
public void init( Context context ) { public void init( Context context ) {
MarkerServiceHandler.init( context );
UiThreadHandler.postDelayed( () -> { UiThreadHandler.postDelayed( () -> {
MogoServices.getInstance().init( AbsMogoApplication.getApp() ); MogoServices.getInstance().init( AbsMogoApplication.getApp() );
}, 5_000L ); }, 5_000L );

View File

@@ -56,6 +56,7 @@ import com.mogo.service.statusmanager.IMogoStatusChangedListener;
import com.mogo.service.statusmanager.IMogoStatusManager; import com.mogo.service.statusmanager.IMogoStatusManager;
import com.mogo.service.statusmanager.StatusDescriptor; import com.mogo.service.statusmanager.StatusDescriptor;
import com.mogo.utils.TipToast; import com.mogo.utils.TipToast;
import com.mogo.utils.UiThreadHandler;
import com.mogo.utils.WorkThreadHandler; import com.mogo.utils.WorkThreadHandler;
import com.mogo.utils.logger.Logger; import com.mogo.utils.logger.Logger;
@@ -273,12 +274,13 @@ public class MogoServices implements IMogoMapListener,
private boolean mIsMainPageFirstResume = true; private boolean mIsMainPageFirstResume = true;
private boolean mIsFirstAccOn = true;
public void init( Context context ) { public void init( Context context ) {
mContext = context; mContext = context;
initWorkThread(); initWorkThread();
MarkerServiceHandler.init( mContext );
mRefreshModel = new RefreshModel( context ); mRefreshModel = new RefreshModel( context );
mMogoMapService = MarkerServiceHandler.getMapService(); mMogoMapService = MarkerServiceHandler.getMapService();
mUiController = mMogoMapService.getMapUIController(); mUiController = mMogoMapService.getMapUIController();
@@ -366,6 +368,7 @@ public class MogoServices implements IMogoMapListener,
if ( msg.obj instanceof RefreshObject ) { if ( msg.obj instanceof RefreshObject ) {
RefreshObject ro = ( ( RefreshObject ) msg.obj ); RefreshObject ro = ( ( RefreshObject ) msg.obj );
if ( ro.mLonLat == null ) { if ( ro.mLonLat == null ) {
Logger.w( TAG, "lonLat is null." );
return; return;
} }
mRefreshModel.refreshData( ro.mLonLat, ro.mRadius, ro.mAmount, ro.mCallback ); mRefreshModel.refreshData( ro.mLonLat, ro.mRadius, ro.mAmount, ro.mCallback );
@@ -619,9 +622,7 @@ public class MogoServices implements IMogoMapListener,
// 自动刷新触发 // 自动刷新触发
final MogoLatLng point = new MogoLatLng( location.getLatitude(), location.getLongitude() ); final MogoLatLng point = new MogoLatLng( location.getLatitude(), location.getLongitude() );
if ( mLastAutoRefreshLocation == null ) { if ( mLastAutoRefreshLocation == null ) {
mLastAutoRefreshLocation = point; startFirstLocationRequest( point );
mLoopRequest = true;
notifyRefreshData( mLastAutoRefreshLocation, getQueryRadius(), mAutoRefreshCallback );
return; return;
} }
float distance = Utils.calculateLineDistance( mLastAutoRefreshLocation, point ); float distance = Utils.calculateLineDistance( mLastAutoRefreshLocation, point );
@@ -635,8 +636,27 @@ public class MogoServices implements IMogoMapListener,
} }
} }
/**
* 首次定位成功后,执行道路事件的刷新
*
* @param point
*/
private void startFirstLocationRequest( MogoLatLng point ) {
mLastAutoRefreshLocation = point;
mLoopRequest = true;
notifyRefreshData( mLastAutoRefreshLocation, getQueryRadius(), mAutoRefreshCallback );
}
@Override @Override
public void onCarLocationChanged2( Location latLng ) { public void onCarLocationChanged2( Location latLng ) {
if ( latLng == null ) {
return;
}
// poi 定位无法获取时,使用该定位
if ( mLastAutoRefreshLocation == null ) {
MogoLatLng point = new MogoLatLng( latLng.getLatitude(), latLng.getLongitude() );
startFirstLocationRequest( point );
}
} }
@Override @Override
@@ -717,18 +737,20 @@ public class MogoServices implements IMogoMapListener,
break; break;
case ACC_STATUS: case ACC_STATUS:
if ( isTrue ) { if ( isTrue ) {
if ( mIsFirstAccOn ) {
mIsFirstAccOn = false;
return;
}
initLocationServiceProcess( mContext ); initLocationServiceProcess( mContext );
mADASController.showADAS(); mADASController.showADAS();
refreshStrategy(); MarkerServiceHandler.getApis().getMapServiceApi().getSingletonLocationClient( mContext ).start();
MarkerServiceHandler.getApis().getMapServiceApi().getSingletonLocationClient( mContext ).stop(); MarkerServiceHandler.getApis().getMapServiceApi().getMarkerManager( mContext ).removeMarkers();
UiThreadHandler.postDelayed( () -> {
refreshStrategy();
}, 3_000L );
} else { } else {
try { MarkerServiceHandler.getApis().getMapServiceApi().getSingletonLocationClient( mContext ).stop();
MarkerServiceHandler.getApis().getMapServiceApi().getMarkerManager( mContext ).removeMarkers(); MarkerServiceHandler.getApis().getMapServiceApi().getMarkerManager( mContext ).removeMarkers();
MarkerServiceHandler.getApis().getMapServiceApi().getSingletonLocationClient( mContext ).start();
} catch ( Exception e ) {
Logger.e( TAG, e, "error." );
}
refreshStrategy();
} }
break; break;
} }

View File

@@ -3,10 +3,11 @@ package com.mogo.module.service.intent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import com.mogo.module.common.utils.CarSeries;
import com.mogo.module.service.MarkerServiceHandler; import com.mogo.module.service.MarkerServiceHandler;
import com.mogo.module.service.ServiceConst; import com.mogo.module.service.ServiceConst;
import com.mogo.module.service.receiver.AccStatusReceiver; import com.mogo.module.service.receiver.AccStatusReceiver;
import com.mogo.module.service.receiver.MogoReceiver; import com.mogo.utils.TipToast;
import com.mogo.utils.logger.Logger; import com.mogo.utils.logger.Logger;
public public
@@ -18,16 +19,21 @@ public
*/ */
class AccStatusIntentHandler implements IntentHandler { class AccStatusIntentHandler implements IntentHandler {
public static final byte ACC_ON = 1;
public static final byte ACC_OFF = 0;
public static final byte ACC_OFF_DELAY = 3;
private static final String TAG = "AccStatusIntentHandler"; private static final String TAG = "AccStatusIntentHandler";
private static volatile AccStatusIntentHandler sInstance; private static volatile AccStatusIntentHandler sInstance;
private AccStatusIntentHandler(){} private AccStatusIntentHandler() {
}
public static AccStatusIntentHandler getInstance(){ public static AccStatusIntentHandler getInstance() {
if( sInstance == null ){ if ( sInstance == null ) {
synchronized( AccStatusIntentHandler.class ) { synchronized ( AccStatusIntentHandler.class ) {
if( sInstance == null ){ if ( sInstance == null ) {
sInstance = new AccStatusIntentHandler(); sInstance = new AccStatusIntentHandler();
} }
} }
@@ -35,7 +41,7 @@ class AccStatusIntentHandler implements IntentHandler {
return sInstance; return sInstance;
} }
public synchronized void release(){ public synchronized void release() {
sInstance = null; sInstance = null;
} }
@@ -43,15 +49,26 @@ class AccStatusIntentHandler implements IntentHandler {
public void handle( Context context, Intent intent ) { public void handle( Context context, Intent intent ) {
String action = intent.getAction(); String action = intent.getAction();
if ( Intent.ACTION_POWER_CONNECTED.equals( action ) ) { if ( Intent.ACTION_POWER_CONNECTED.equals( action ) ) {
MarkerServiceHandler.getMogoStatusManager().setAccStatus( ServiceConst.TYPE, true ); if ( CarSeries.getSeries() == CarSeries.CAR_SERIES_F80X ) {
Logger.d( TAG, "acc status: %s", true ); MarkerServiceHandler.getMogoStatusManager().setAccStatus( ServiceConst.TYPE, true );
Logger.d( TAG, "acc status: %s", true );
}
} else if ( Intent.ACTION_POWER_DISCONNECTED.equals( action ) ) { } else if ( Intent.ACTION_POWER_DISCONNECTED.equals( action ) ) {
MarkerServiceHandler.getMogoStatusManager().setAccStatus( ServiceConst.TYPE, false ); if ( CarSeries.getSeries() == CarSeries.CAR_SERIES_F80X ) {
Logger.d( TAG, "acc status: %s", false ); MarkerServiceHandler.getMogoStatusManager().setAccStatus( ServiceConst.TYPE, false );
Logger.d( TAG, "acc status: %s", false );
}
} else if ( AccStatusReceiver.ACTION_NWD_ACC.equals( action ) ) { } else if ( AccStatusReceiver.ACTION_NWD_ACC.equals( action ) ) {
int state = intent.getByteExtra( AccStatusReceiver.PARAM_ACC_STATUS, ( byte ) 0 ); int state = intent.getByteExtra( AccStatusReceiver.PARAM_ACC_STATUS, ACC_OFF );
Logger.d( TAG, "acc status: %s", state == 1 ); if ( state != ACC_OFF && state != ACC_ON && state != ACC_OFF_DELAY ) {
MarkerServiceHandler.getMogoStatusManager().setAccStatus( ServiceConst.TYPE, state == 1 ); return;
}
boolean accOn = state == ACC_ON;
if ( MarkerServiceHandler.getMogoStatusManager().isAccOn() == accOn ) {
return;
}
Logger.d( TAG, "acc status: %s", state );
MarkerServiceHandler.getMogoStatusManager().setAccStatus( ServiceConst.TYPE, accOn );
} }
} }
} }

View File

@@ -77,7 +77,6 @@ public class MapMarkerManager implements IMogoMarkerClickListener,
private Rect mMarkerDisplayBounds; private Rect mMarkerDisplayBounds;
private MapMarkerManager() { private MapMarkerManager() {
mContext = AbsMogoApplication.getApp();
} }
public static synchronized MapMarkerManager getInstance() { public static synchronized MapMarkerManager getInstance() {
@@ -96,6 +95,12 @@ public class MapMarkerManager implements IMogoMarkerClickListener,
* @param context * @param context
*/ */
public void init( Context context ) { public void init( Context context ) {
if ( mContext != null ) {
return;
}
mContext = context.getApplicationContext();
mRefreshModel = new RefreshModel( mContext ); mRefreshModel = new RefreshModel( mContext );
// 长连接 // 长连接

View File

@@ -1,24 +0,0 @@
package com.zhidao.mogo.module.splash
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.zhidao.mogo.module.byd.test", appContext.packageName)
}
}

View File

@@ -1,17 +0,0 @@
package com.zhidao.mogo.module.splash
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}