import android.content.Intent ;
import android.net.Uri ;
public static void openAppStore( final String url ) {
Intent viewIntent = new Intent(Intent.ACTION_VIEW,Uri.parse( url ));
// "android.intent.action.VIEW"
mContext.startActivity(viewIntent);
}
- use LOCAL_WHOLE_STATIC_LIBRARIES instead of LOCAL_STATIC_LIBRARIES
import android.os.Looper ;
public static boolean isMainThread() {
return Looper.getMainLooper().getThread() == Thread.currentThread();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// prevent auto restarting rather than resuming
// on some android device
if (!isTaskRoot()
&& getIntent().hasCategory(Intent.CATEGORY_LAUNCHER)
&& getIntent().getAction() != null
&& getIntent().getAction().equals(Intent.ACTION_MAIN)) {
finish();
return;
}
...
mActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText( mActivity , str, Toast.LENGTH_SHORT ).show();
}
});
- more details : Cocos2dxHelper
private static Handler mWorkingHandler = null ;
private static Thread mWorkingThread = null;
// should be initially called by working thread
public static void setWorkingThread() {
if ( mWorkingThread == null )
mWorkingThread = Thread.currentThread();
}
public static void runOnWorkingThread( Runnable action ) {
if ( mWorkingThread == null )
return ;
if ( mWorkingHandler == null ) {
// Default constructor associates this handler with the Looper for the current thread.
mWorkingHandler = new Handler() ;
}
if (Thread.currentThread() != mWorkingThread) {
mWorkingHandler.post(action);
} else {
action.run();
}
}
in your app level build.gradle
dependencies {
implementation 'com.google.code.gson:gson:2.2.1'
}
using in your android project
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.util.HashMap;
/**
* This class provides basic/common functionalities to be applied on Java Objects.
//*/
public final class ObjectUtils {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private ObjectUtils() {
throw new UnsupportedOperationException("Instantiation of this class is not permitted in case you are using reflection.");
}
/**
* This method is responsible for de-serializing the Java Object into Json String.
*
* @param object Object to be de-serialized.
* @return String
*/
public static String deserializeObjectToString(final Object object) {
return GSON.toJson(object);
}
public static HashMap<String,Object> json2map( String json ) {
HashMap<String,Object> map = new HashMap<String,Object>();
map = (HashMap<String,Object>) GSON.fromJson(json, map.getClass());
return map ;
}
}
to use:
import com.google.gson.internal.StringMap;
...
HashMap<String,Object> map = ObjectUtils.json2map( response.toString() );
StringMap<String> ret_data = (StringMap<String>)map.get( "data" );
- This class was deprecated in API level 30.
- Use the standard java.util.concurrent or Kotlin concurrency utilities instead.
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
// invoked on the UI thread before the task is executed.
// This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
protected void onPreExecute() {
super.onPreExecute();
Log.d(TAG + " PreExceute","On pre Exceute......");
}
// invoked on the background thread immediately after onPreExecute() finishes executing.
// The parameters of the asynchronous task are passed to this step.
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
// This step can also use publishProgress(Progress...) to publish one or more units of progress.
// These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
// invoked on the UI thread after a call to publishProgress(Progress...).
// This method is used to display any form of progress in the user interface while the background computation is still executing.
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
// invoked on the UI thread after the background computation finishes.
// The result of the background computation is passed to this step as a parameter.
showDialog("Downloaded " + result + " bytes");
}
}
Once created, a task is executed very simply:
new DownloadFilesTask().execute(url1, url2, url3);
sometime you just want to do some simple test, and don't care about whether AsyncTask will freeze the UI thread ...
TYPE ret = new DownloadFilesTask().execute(url1, url2, url3).get() ;
android update project -p . -t android-23
ant debug
# just for example, using NDK r20
$NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-readelf -A <.so file>
$NDK/toolchains/llvm/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-readelf -d ../dist/Android/libs/armeabi-v7a/libgo.so
A layout is made up of definitions written in XML. Each definition is used to create an object that appears on screen, like a button or some text.
An activity is the java code which attaches actions and puts content to/in a layout.
For this the Activity loads the layout.
This is how layouts gets connected to our activity.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// connect layout to activity
// activity_main.xml is the layout XML file
setContentView(R.layout.activity_main)
}
}
When we're putting some views inside of another view, the Constraint Layout is called out.
Constraint Layout lets us position the sub-views by using constraints, which makes creating a layout super simple.
You can drag the white circle to edge of the screen to make the connection.
Each view has it's own ID. sometimes you'd better to rename the default ID to a meaningful name.
We can access any view by its ID.
import android.widget.Button
...
setContentView(R.layout.activity_main)
// PS. Must invoke findViewById after `setContentView` finish
val rollButton = findViewById<Button>( R.id.rollButton )
val resultsTextView = findViewById<TextView>( R.id.resultTextView )
val seekBar = findViewById<SeekBar>(R.id.seekBar2)
rollButton.setOnClickListener {
Log.d( "MyApp", "roll dice" )
val rand = Random().nextInt( seekBar.progress + 1 )
resultsTextView.text = rand.toString()
}