2019 software engineering application and practice - artificial intelligence express cabinet (code analysis 7)

Keywords: Android AI


public class CabinetService extends Service {}

Create a CabinetService class, which inherits from the Service class
The specific contents of the class are analyzed as follows:

private String TAG = CabinetService.class.getSimpleName();
    public class LocalBinder extends Binder {
        public CabinetService getService() {
            return CabinetService.this;

First, create the Binder object, return it to the client, that is, the Activity uses it, provide the interface for data exchange, and declare a method, getService, which is provided to the client for calling. In the method, return the current object LocalService, so that we can call the public method of Service on the client side.

    int mStartMode;
    IBinder mBinder;
    boolean mAllowRebind;

The three variables defined represent: identify the behavior of the service if it is killed; Binding client interface; Identifies whether onRebind can be used. It is convenient to simplify the code later.

public void onCreate() {

        MqttUtils.addMqttObserver(new CabinetObserver(this));

        Log.e(TAG, "service is created");
        MqttSchedule schedule = new MqttSchedule();

The onCreate() method is redefined, which uses the mqtt timed detection task

    public int onStartCommand(Intent intent, int flags, int startId) {

        Log.e(TAG, "service is Start");

        return mStartMode;

Callback when calling startService() to start the service

    public IBinder onBind(Intent intent) {
        Log.e(TAG, "service is onBind");
        return mBinder;

Clients bound to the service through bindService()

    public boolean onUnbind(Intent intent) {
        Log.e(TAG, "service is onUnbind");
        return mAllowRebind;

Called when all clients are unbound through unbindService()

    public void onRebind(Intent intent) {
        Log.e(TAG, "service is onRebind");


Called when a client is bound to a service through bindService()

    public void onDestroy() {
        Log.e(TAG, "service is onDestroy");


Called when the service is no longer useful and is about to be destroyed

@Subscribe(threadMode = ThreadMode.MAIN)
    public void snycResult(String msg){
        if (msg.equals("overWrite")){

            Log.e(TAG, msg);
        }else {
            Log.e(TAG, "Shadow synchronization error");
           //Toast.makeText(this, "shadow synchronization error:" + msg,Toast.LENGTH_LONG);

At this time, the ThreadMode thread mode is the MAIN mode. When the MAIN thread processes events, if the sub thread sends messages, the thread will be switched to the MAIN thread when processing messages. There are two MAIN situations:

  • If the thread sending the event is the main thread, call the message processing event immediately, and the main thread will block;
  • If the thread sending the event is a child thread, the event is queued in the queue for delivery, and the publishing thread will not be blocked;

If the database is rewritten, read all data in the database and update the page; When the database is not rewritten, the seniors used Toast.makeText(this, "shadow synchronization error:" + msg,Toast.LENGTH_LONG); To resend the previous request and continue the blocked original master process, but this use is an error. The reason analysis is as follows: when using Toast to pop up a message in a child thread, go to the corresponding location to get the object. The child thread directly gets the object without initialization, and the result must not be obtained, so this exception will be thrown. This is that Toast cannot be used directly in the child thread. If it is used, the prepare() function needs to be added.

public void update(List<List<NotifyDataDetails>> list){
        //list.get(0) is the class name and sri of the added data
        //list.get(1) is the class name and sri of the updated data
        //list.get(2) is the class name and sri of the deleted data
        Log.e(TAG, JSON.toJSONString(list));

        List<NotifyDataDetails> addDataDetailsList = list.get(0);
        for (NotifyDataDetails addDetail : addDataDetailsList) {
            switch (addDetail.getClassName()) {
                case "SduMedia":
                    SduMedia media = (SduMedia) DaoManager.search(new SduMedia(), addDetail.getSri());
                    if (media == null) {
                        Log.e(TAG, "Received an empty mediaļ¼ŒThe information is as follows: " + JSON.toJSONString(addDetail));
                    Log.e(TAG, media.getPath());
                    if (!media.getDownloaded()) {

                        MinioUtil.downloadByUrl(media.getPath(), (InputStream is) -> {
                            if (is != null) {
                                Log.e(TAG, "file separator " + File.separator);
                                String[] strs = media.getPath().split(File.separator);
                                String fileName = strs[strs.length - 1];
                                FileUtil.saveFile(is, fileName);
                                media.setAnPath(FileUtil.path + File.pathSeparator + fileName);



This method mainly manages the publicity and display part (mainly the publicity map) on the cabinet end interface. Media is a customized media file object. The if continue section mainly explains that no error will be reported when the media file does not exist. When the media file exists, if the media file is not downloaded to the local machine, immediately initiate a network request, download the file to the local machine, and execute a callback after completion. use

media.setAnPath(FileUtil.path + File.pathSeparator + fileName);

Update the downloaded flag bit of the current media in the shadow, and update the file storage location url at the same time; Update the database; Send to the background and notify the front-end media component to update the media list

Posted by AndrewJ1313 on Sun, 21 Nov 2021 13:35:11 -0800