Complete Solution: Command mode + asynchronous execution + cancellation mechanism, asynchronous mechanism
Introduction
- With the development of the project, the code of the activity becomes more and more complex and difficult to maintain. In this case, modes such as MVP are implemented hierarchically to reduce the negative effects on the activity, thus reducing the coupling of business logic and improving maintainability. This article uses the command mode to slim down the activity from another perspective. This solution also removes the business logic and executes it in the background. It also provides a good cancellation mechanism.
Interface
- ICmd interface. The main api is the exe method, and the returned value is the bundle object. Other mtags and mCanceled are used to cancel the related
public abstract class iCmd { private boolean mCanceled = false; private Object mTag; public void cancel() { mCanceled = true; } public boolean isCanceled() { return mCanceled; } public Object getTag() { return mTag; } public iCmd setTag(Object tag) { mTag = tag; return this; } public abstract Bundle exe() throws Exception;}
- ICmdListener command listening interface, onPreExecute is responsible for the notification of command start; onPostExecute is responsible for the notification of command end and return results
public interface iCmdListener { public void onPreExecute();// public void onProgressUpdate(int progress); public void onPostExecute(Bundle resultBundle);}
- ICmdExecutor command executor. The following code only lists the main APIs. The github address after the specific implementation is as follows:
Public class iCmdExecutor {// used to cancel cmd public static void cancelAll (final Object tag) related to a specific tag // run this command asynchronously, and execute the callback notification in the main thread to notify public static void exeAsync (final iCmd cmd, final iCmdListener listener, Object tag) // synchronously execute this command, and execute callback notification public static void exeSync (iCmd cmd, iCmdListener listener, Object tag )}
Usage
public class CmdAdd extends iCmd { private static final String TAG = "test"; private BigInteger a; private BigInteger b; public CmdAdd(BigInteger a, BigInteger b) { this.a = a; this.b = b; } @Override public Bundle exe() throws InterruptedException { Log.i(TAG, this + ", exe, tid=" + Thread.currentThread().getId()); Thread.sleep(5000);// demo for long operation Bundle bundle = new Bundle(); bundle.putString("result", a.add(b).toString()); return bundle; }}
iCmdExecutor.exeAsync(new CmdAdd(new BigInteger("123"), new BigInteger( "12345678901234567890123456789012345678901234567890")), new iCmdListener() { @Override public void onPreExecute() { Log.e(TAG, "onPreExecute, tid=" + Thread.currentThread().getId()); } @Override public void onPostExecute(Bundle resultBundle) { Log.e(TAG, "onPostExecute, tid=" + Thread.currentThread().getId() + ", resultBundle=" + resultBundle); if (null != resultBundle) { String res = resultBundle.getString("result"); tvAddResult.setText(res); } } }, this);
- Cancel when activity exits
iCmdExecutor.cancelAll(this);
Link
- Https://github.com/cheyiliu/AsyncCmdForAndroid