Introduction level use and partial parsing of xUitls3 framework

Article Directory

Getting Started with xUtils3 and Parsing Part

Introduction to xUtils

xUitls is a third-party library, a tool class originally derived from the Afinal framework, which has been heavily refactored to support large file uploads and safer Http request protocol support.

It is mainly divided into four modules: DbUtils, HttpUtils, ViewUtils, BitmapUtils

DbUtils:

  • orm framework in android, one line of code can be added, deleted and modified;
  • Supports transactions and closes by default;
  • You can customize table names, column names, foreign keys, uniqueness constraints, NOT NULL constraints, CHECK constraints, etc. by annotating them (annotate table names and column names when confusion is needed);
  • Supports binding foreign keys, which are automatically saved or updated when an entity is saved.
  • Automatically loads foreign key associated entities, supporting delayed loading;
  • Support chained representation of queries, more intuitive query semantics, refer to the following description or sample examples.

ViewUtils:

  • ioc framework in android, fully annotated for UI, resource and event binding;
  • The new event binding method can still work well after being confused with obfuscation tools.
  • Currently supports 20 common event bindings, see ViewCommonEventListener classes and packagesCom.lidroid.xutils.View.annotation.event.

HttpUtils:

  • Support synchronous, asynchronous requests;
  • Support large file upload, large file upload will not oom;
  • Support GET, POST, PUT, MOVE, COPY, DELETE, HEAD, OPTIONS, TRACE, CONNECT requests;
  • Download supports 301/302 redirection and whether to rename downloaded files according to Content-Disposition.
  • Requests that return text content (only GET requests are enabled by default) support caching, which sets the default expiration time and the expiration time for the current request.

BitmapUtils:

  • When loading bitmaps, it is not necessary to consider the picture misalignment that occurs during the loading of bitmaps when oom and android containers are sliding rapidly.
  • Support loading network and local pictures;
  • Memory management uses lru algorithm to better manage bitmap memory;
  • Configurable Threads Load Threads Number, Cache Size, Cache Path, Load Display Animation, etc...

Since xUtils has not been updated for a long time, we are now using its upgraded version, xUtils3

This is its Official website

xUtils3 has changed a little from the older version:

  • The HTTP implementation replaces HttpClient as UrlConnection, automatically resolves callback generics, and provides a safer breakpoint continuation policy.

  • Supports standard Cookie policies, distinguishes domain from path;

  • Event annotations remove less commonly used functions and improve performance;

  • Database api simplification improves performance to match greenDao performance.

  • Picture binding supports gif (some GIF files can only be displayed statically due to system compatibility), webp; round, square clipping, etc., and automatic rotation.



Practice section:

Set up initialization environment

1.Gradle builds with the following dependencies:

implementation 'org.xutils:xutils:3.8.9'

2. Join the required permissions:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!-- Optional -->

3. Initialize (remember to initialize in application, which is inconsistent with older versions)

// Initialize in onCreate of application
@Override
public void onCreate() {
    super.onCreate();
    x.Ext.init(this);
    x.Ext.setDebug(BuildConfig.DEBUG); // Whether debug log is output or not, opening debug will affect performance.
    ...
}

4. References in the configuration file:

5. Also declare in MainActivity

Add the following code:

x.view().inject(this);

Up to this point, the initialization of xUitls3 has been completed and functionality can be used.



Use of ViewUtils module

The use of ViewUtils does not require findViewById, setClickListener, etc. It has been replaced with annotations, greatly simplifying our development.Here are a few common notes

@ContentView()

What is this comment?

Obviously, by name, we know that it is a replacement for **setContentView()**

How does it work?

Let's click on its source code

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ContentView {
    int value();
}

As you can see, in this comment, you just need Value to fill in your layout file id.Then label it on your Activity

@ViewInject()

What is this comment?

By literally translating this note it is clear that it is used to inject the view, that is, it replaces our findViewById()

How does it work?

Source code:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewInject {
    int value();
    /* parent view id */
    int parentId() default 0;
}

As you can see, it only needs to be injected with value and labeled on the TextView.

Example:
    @ViewInject(R.id.queryname)
    TextView tv;

@Event()

This comment is used primarily for event handling.

Source code:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Event {

    /**
     * Control's id collection, if id is less than 1, does not perform ui event binding.
     */
    int[] value();

    /**
     * The id collection of the parent control of the control, grouped into (value[i], parentId[i] or 0).
     */
    int[] parentId() default 0;

    /**
     * Event listener, default to click event.
     */
    Class<?> type() default View.OnClickListener.class;

    /**
     * The setter method name of the event, defaulting to set+type#simpleName.
     */
    String setter() default "";

    /**
     * If the type's interface type provides more than one method, you need to specify the method name using this parameter.
     */
    String method() default "";
}

Here are a few points to note:

  • Annotation methods must be modified with private s
  • No requirement for return value type
  • Consistent parameter names are required for the interface of the parameter name and type
  • Multiple value values enclosed in {}

For example:

 @Event(value = {R.id.btn1,R.id.btn2,R.id.btn3})
    private void onClick(View v) {
        switch (v.getId()){
            case R.id.btn1 :
                Toast.makeText(getApplicationContext(),"btn1 Clicked on",Toast.LENGTH_LONG).show();
            case R.id.btn2 :
                Toast.makeText(getApplicationContext(),"btn2 Clicked on",Toast.LENGTH_LONG).show();
            case R.id.btn3 :
                Toast.makeText(getApplicationContext(),"btn3 Clicked on",Toast.LENGTH_LONG).show();
        }
    }



Use of DbUtils module

First, we have a new one in MainActivity DbManager.DaoConfig

What does this DaoConfig have?Here's a summary:

  public DaoConfig setDbDir(File dbDir)		#Set up database storage directory
  public DaoConfig setDbName(String dbName)		#Set Database Name
  public DaoConfig setDbVersion(int dbVersion)	#Set Database Version
  public DaoConfig setAllowTransaction(boolean allowTransaction)	#Set whether to open a transaction (default istrue)
  public DaoConfig setDbOpenListener(DbOpenListener dbOpenListener)		#Database Open Listening
  public DaoConfig setDbUpgradeListener(DbUpgradeListener dbUpgradeListener)	#Database Update Listening
  public DaoConfig setTableCreateListener(TableCreateListener tableCreateListener)	#Listen Table Creation

With that in mind, we can start configuring:

1. Create and configure a DbManager

@ContentView(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
    DbManager db;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       // setContentView(R.layout.activity_main);
		//Create and configure DaoConfig
        DbManager.DaoConfig daoConfig = new DbManager.DaoConfig()
                .setDbName("test1.db")
                .setDbDir(new File("/sdcard"))
                .setDbVersion(2)
                .setDbOpenListener(new DbManager.DbOpenListener() {
                    @Override
                    public void onDbOpened(DbManager db) throws DbException {
                       //Turn on WAL to improve writing speed
                        db.getDatabase().enableWriteAheadLogging();
                    }
                })
                .setDbUpgradeListener(new DbManager.DbUpgradeListener() {
                    @Override
                    public void onUpgrade(DbManager db, int oldVersion, int newVersion) throws DbException {
                        //Can do related operations such as table building
                    }
                });


        try {
            db = x.getDb(daoConfig);
        } catch (DbException e) {
            e.printStackTrace();
        }


    }
}

2. Create entity classes

Next, create a User table as the entity class for the database: (the purpose of the specific note is indicated)

//Declare it as a table, give xutils parse table name user, fill sql statement at onCreated, table creation will execute (default is empty)
@Table(name="user",onCreated = "")
public class User {
    
    //isId tells xutils that it is id and whether the autoGen setting increases itself
    @Column(name = "id",isId = true,autoGen = true,property = "NOT NULL")
    private int id;
    
    @Column(name = "name")
    private String name;
    
    //Be careful to keep this parameterless construct, otherwise table building will fail
    public User(){

    }

    public User(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

3. Implement CRUD method

CRUD method using DbManager in MainActivity:

(The **@Event** annotation, which simply passes in the id of the button, allows us to listen for the button in the labeling method, saving us a lot of effort)

  @Event(R.id.save)
        private void save(View v) throws DbException {
        ArrayList<User> users = new ArrayList<>();
            users.add(new User("zhangsan"));
            users.add(new User("lisi"));
            //Not only can you insert a single user, you can also insert a List
            db.save(users);
             Log.i("test","Table building successful");
    }

    @Event(R.id.delete)
    private void del(View v) throws DbException {
        //whereBuilder is a conditional class in which conditional SQL statements can be run
        //Incoming id = 1
        db.delete(User.class, WhereBuilder.b().and("id","=",1));
        Log.i("test","Delete succeeded");
    }

    @Event(R.id.update)
    private void update(View v) throws DbException {
        //Change the name value of the data with id=1 to Nick
        db.update(User.class,WhereBuilder.b().and("id","=",1),new KeyValue("name","Nick"));
        Log.i("test","Successful modification");
    }

    @Event(R.id.query)
    private void select(View v) throws DbException {
        //Find the value with id=1
       User user = db.selector(User.class).where("id","=",1).findFirst();
        Log.i("test","User name:"+user.getName());
        Toast.makeText(getApplicationContext(),user.getName(),Toast.LENGTH_LONG).show();
    }

The results are as follows:



Use of HttpUtils module

Usually, our Get request has a long string of character parameters that follow the request address, and HttpUtils allows it to form a string that is encapsulated directly into the request method like a Post request, while also setting custom properties.


Get Request

First let's do the Get request:

Add the following code to a button's listening event: x.http().get(), and we click into the method to see what parameters are required.

 /**
     * Asynchronous GET Request
     */
    <T> Callback.Cancelable get(RequestParams entity, Callback.CommonCallback<T> callback);

It needs a RequestParams and a Callback, what can I do?Newit.Here is the implementation of the get request:

    @Event(R.id.get)
    public void Get(View v){
        RequestParams params = new RequestParams(url);
        //Add parameters
        params.addQueryStringParameter("username","zahngsan");
        params.addQueryStringParameter("password","1234");

        x.http().get(params, new Callback.CacheCallback<String>() {
            //Success
            @Override
            public void onSuccess(String result) {
                
            }
            //fail
            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                
            }
            //Actively Cancel Callback
            @Override
            public void onCancelled(CancelledException cex) {
                
            }
            //Callbacks Requesting Completion
            @Override
            public void onFinished() {
                
            }
            //cache
            @Override
            public boolean onCache(String result) {
                return false;
            }
        });
    }

Post Request

Similarly, we can write a post request:

 @Event(R.id.post)
    public void Post(View v){
        RequestParams params = new RequestParams(url);
        //Add parameters
        params.addBodyParameter("username","zahngsan");
        params.addParameter("password","1234");
        //Request Header
        params.addHeader("head","test");

        x.http().get(params, new Callback.CacheCallback<String>() {
            //Success
            @Override
            public void onSuccess(String result) {
                
            }
            //fail
            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                
            }
            //Actively Cancel Callback
            @Override
            public void onCancelled(CancelledException cex) {
                
            }
            //Callbacks Requesting Completion
            @Override
            public void onFinished() {
                
            }
           
        });
    }

It also supports uploading and downloading files.

Upload Files

@Event(R.id.up)
private void up(View v){
	String path="/mnt/sdcard/Download/nick.jpg";
	RequestParams params = new RequestParams(url);
	params.setMultipart(true);
	params.addBodyParameter("file",new File(path));
	x.http().post(params, new Callback.CommonCallback<String>() {
   	 	@Override
   		public void onSuccess(String result) {
   	 }
   		@Override
    	public void onError(Throwable ex, boolean isOnCallback) {
    	}
    	@Override
    	public void onCancelled(CancelledException cex) {
    	}
    	@Override
   		public void onFinished() {
    	}
	});
  }

Download Files

  @Event(R.id.down)
    private void down(View v){
        String url = "https://down.qq.com/qqweb/QQ_1/android_apk/Android_8.3.6.4590_537064458.apk";

        RequestParams params = new RequestParams(url);
        //Define the directory of storage
        params.setSaveFilePath(Environment.getExternalStorageDirectory()+"/test");
        //Set file auto-naming
        params.setAutoRename(true);

        x.http().post(params, new Callback.ProgressCallback<File>() {
            @Override
            public void onSuccess(File result) {
                //When the apk download is complete, call the installation method of the system
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(Uri.fromFile(result), "application/vnd.android.package-archive");
                startActivity(intent);
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {

            }

            @Override
            public void onCancelled(CancelledException cex) {

            }

            @Override
            public void onFinished() {

            }
            //Callback before network request
            @Override
            public void onWaiting() {

            }
            //Callback to start the request
            @Override
            public void onStarted() {

            }
            //Edge Request Edge Call Method
            @Override
            public void onLoading(long total, long current, boolean isDownloading) {
                Log.i("test","current="+",total="+total);
            }
        });
    }



Use of BitmapUtils module

xUtils3 adds support for gif, rounded corners, squares, and so on, based on xUtils'picture binding.This section focuses on the four bind methods for loading pictures, the loadDrawable and loadFIle usages, and the ImageOptions usage.

First, I can open the interface of **x.image().bind()** and feel its source code, so I can recognize it from the source code

public interface ImageManager {

    void bind(ImageView view, String url);

    void bind(ImageView view, String url, ImageOptions options);

    void bind(ImageView view, String url, Callback.CommonCallback<Drawable> callback);

    void bind(ImageView view, String url, ImageOptions options, Callback.CommonCallback<Drawable> callback);

    Callback.Cancelable loadDrawable(String url, ImageOptions options, Callback.CommonCallback<Drawable> callback);

    Callback.Cancelable loadFile(String url, ImageOptions options, Callback.CacheCallback<File> callback);

    void clearMemCache();

    void clearCacheFiles();
}

You can see that there are four overloaded bind methods

lmageOptions

Let's see what its ImageOptions can do:

setFadeIn(true)		//Set fade-in effect
setCircular(true) 	//Set the picture to show as a circle
setSquare(true)		//Set the picture to be square
setCrop(true).setSize(100,100)	//Set Picture Size
setAnimation(animation)	//Set Animation
setFailureDrawable(Drawable failureDrawable)	//Set the animation that failed to load
setFailureDrawableId(int failureDrawable) 	//Failed animation loaded with resource id settings
setLoardingDrawable(Drawable loardingDrawable)	//Set animation in load
setLoadingDrawableId(int loadingDrawable) //Set animation in load with resource id
setParamsBuilder(ParamsBuilder paramsBuilder)	//Add parameters to network requests
setIgnoreGif(false) 	//Ignore Gif Pictures
setRaduis(int raduis) 	//Set corner radians
setUseMemCache(true)	//Set up to use MemCache

bind

Here I would like to briefly introduce the use of one of the bind methods:

@ContentView(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
    String url = "https://i.picsum.photos/id/1/5616/3744.jpg";
    @ViewInject(R.id.img)
    ImageView iv;

    @ViewInject(R.id.tv)
    TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        x.view().inject(this);

        ImageOptions options = new ImageOptions.Builder()
                .setFadeIn(true)
                .setCrop(true)
                .setSize(300,300).build();
        x.image().bind(iv, url,options, new Callback.CacheCallback<Drawable>() {
            @Override
            //cache
            public boolean onCache(Drawable result) {
                return false;
            }

            @Override
            public void onSuccess(Drawable result) {
                tv.setText("Pictures loaded successfully");
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                tv.setText("Picture Loading Error");
            }

            @Override
            public void onCancelled(CancelledException cex) {

            }

            @Override
            public void onFinished() {

            }
        });
	}
}

Run result:

loadDrawable

Next, learn loadDrawable, which actually works like bind, but it saves the loaded pictures locally

 x.image().loadDrawable(url,options, new Callback.CommonCallback<Drawable>() {
            @Override
            public void onSuccess(Drawable result) {
                 iv.setImageDrawable(result);
                tv.setText("Pictures loaded successfully");
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                tv.setText("Picture Loading Error");
            }

            @Override
            public void onCancelled(CancelledException cex) {
            }

            @Override
            public void onFinished() {
            }
        });

loadFile

Finally, let's take a look at the loadFile method, which can be used to get images saved with loadDrawable

 x.image().loadFile(url, options, new Callback.CacheCallback<File>() {
            @Override
            public boolean onCache(File result) {
                //Use local pictures
                Log.i("test",result.getPath());
                return true;
            }

            @Override
            public void onSuccess(File result) {
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
            }

            @Override
            public void onCancelled(CancelledException cex) {
            }

            @Override
            public void onFinished() {
            }
        });

Finally, let's take a look at the loadFile method, which can be used to get images saved with loadDrawable

 x.image().loadFile(url, options, new Callback.CacheCallback<File>() {
            @Override
            public boolean onCache(File result) {
                //Use local pictures
                Log.i("test",result.getPath());
                return true;
            }

            @Override
            public void onSuccess(File result) {
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
            }

            @Override
            public void onCancelled(CancelledException cex) {
            }

            @Override
            public void onFinished() {
            }
        });

Do not stumble to thousands of miles

Tags: Android Database network Gradle

Posted on Thu, 04 Jun 2020 12:02:28 -0700 by ShugNorris