Search code examples
javaandroidandroid-asynctask

How to use AsyncTask correctly?


How to use Asynctask correctly in this case? So in some App I've got the exception: "android.os.NetworkOnMainThreadException"

And one way to solve it are using Asynctask

But how to use it in this case?

package com.mycompany.myapp;

import android.app.*;
import android.os.*;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.widget.FrameLayout;
import java.io.*;
import java.net.*;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;
import android.widget.Toast;
import android.view.View;
import android.text.Html;
import java.util.Scanner;
import com.mycompany.myapp.client.HCUser;
import com.mycompany.myapp.common.*;
import android.content.SharedPreferences;
import android.content.Context;
import com.mycompany.myapp.common.constants.*;
import java.util.ArrayList;
import Misc.Settings;
import com.mycompany.myapp.client.*;
import java.nio.channels.SocketChannel;
import com.mycompany.myapp.client.packages.tcp.P2;
import com.mycompany.myapp.common.packages.tcp.HPackage;
import com.mycompany.myapp.common.serialization.HPackageSerializer;

public class MainActivity extends AppCompatActivity implements Runnable
{
    FrameLayout simpleFrameLayout;
    TabLayout tabLayout;
    static Socket sock = new Socket();
    static OutputStream out = null;
    static DataInputStream dIn;
    FirstFragment f = new  FirstFragment();
    SecondFragment s = new SecondFragment();
    
    private HCUser user;
    private Thread reader;
    private Timer updateTimer;
    private boolean running;
    private SocketChannel socket;
    
    public static final String CLIENT_VERSION = "Rs 0.09";
    
    TabLayout.Tab secondTab;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
// get the reference of FrameLayout and TabLayout
        simpleFrameLayout = (FrameLayout) findViewById(R.id.simpleFrameLayout);
        tabLayout = (TabLayout) findViewById(R.id.simpleTabLayout);
// Create a new Tab named "First"
        TabLayout.Tab firstTab = tabLayout.newTab();
        firstTab.setText("First"); // set the Text for the first Tab
         
// first tab
        tabLayout.addTab(firstTab); // add  the tab at in the TabLayout
// Create a new Tab named "Second"
        secondTab = tabLayout.newTab();
        secondTab.setText("Second"); // set the Text for the second Tab
        
        tabLayout.addTab(secondTab); // add  the tab  in the TabLayout

        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.add(R.id.simpleFrameLayout, f);
        ft.add(R.id.simpleFrameLayout, s);
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        ft.commit();
        ft.hide(s);
        
        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
                @Override
                public void onTabSelected(TabLayout.Tab tab) {
// get the current selected tab's position and replace the fragment accordingly
                    FragmentTransaction ft3 = getSupportFragmentManager().beginTransaction();
                    switch (tab.getPosition()) {
                        case 0:
                            if(f.isAdded()){
                                ft3.show(f);
                                ft3.commit();
                                if(s.isAdded()){ft3.hide(s);}
                            }
                            
                            
                            break;
                        case 1:
                            if(s.isAdded()){
                                ft3.show(s);
                                ft3.commit();
                                if(f.isAdded()){ft3.hide(f);}
                            }
                            
                            
                            break;
                    }
                    
                }

                @Override
                public void onTabUnselected(TabLayout.Tab tab) {

                }

                @Override
                public void onTabReselected(TabLayout.Tab tab) {

                }
            });
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menuopciones, menu);
        return true;
    }
    
    public void conectar(String nombre, String ip, int puerto) throws UnknownHostException{
        SharedPreferences prefe=this.getApplicationContext().getSharedPreferences("datos", Context.MODE_PRIVATE);
        HCUser usuario = new HCUser(prefe.getString("usuario",""), (short)0, HLineType.HLNone, HBrowsable.Not_Browsable, (byte)prefe.getInt("edad",0), getgender(prefe.getInt("sexo",-1)), contains(prefe.getInt("pais",-1)), prefe.getString("estado",""), Settings.LocalIP(), (short)Settings.Port(), Settings.LocalIP(), InetAddress.getByName("0.0.0.0"), (short)65535, (byte)0, (byte)0, (byte)0);
        this.user = usuario;
        this.reader = new Thread(this);
        this.reader.setPriority(Thread.MAX_PRIORITY);
        this.updateTimer = new Timer(new Runnable() {
                public void run() {

                }
            }, 80000, false);
        this.running = false;
        try{
            connect(InetAddress.getByName(ip),puerto, nombre);
        }
        catch(Exception e){
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw));
            String stacktrace = sw.toString();

            // create an email intent to send to yourself
            final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
            emailIntent.setType("plain/text");
            emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[] { "[email protected]" });
            emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "App Error Report");
            emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, stacktrace);

            // start the email activity - note you need to start it with a chooser
            startActivity(Intent.createChooser(emailIntent, "Send error report..."));
        }
    }

    public static HGender getgender(int num){
        if(num==0){
            return HGender.Unknow;
        }
        if(num==1){
            return HGender.Male;
        }
        return HGender.Female;
    }
    
    public static HLocation contains(int test) {

        if(test >= 47 && test < 87){
            test = test + 1;
            return HLocation.get((byte)test);
        }
        if(test >= 87 && test < 89){
            test = test + 2;
            return HLocation.get((byte)test);
        }
        test = test + 3;
        return HLocation.get((byte)test);
    }
    
    public void connect(InetAddress ip, int port, String nombre) throws IOException {
        InetSocketAddress addr = new InetSocketAddress(ip, port);
        connect(addr, nombre);
    }

    public void connect(SocketAddress addr, String nombre) throws IOException {

        try {
            socket = SocketChannel.open();
            socket.socket().connect(addr, 1000);
            TabLayout.Tab tab = tabLayout.getTabAt(1);
            tab.select();
            s.room.setText(nombre);
            socket.configureBlocking(true);

            while (!socket.finishConnect()) {

            }
            running = true;
            if (!reader.isAlive()) {
                reader.start();
            }
            P2 pkg = new P2(user.getGuid(), (short) user.getFilecount(), (short) user.getDataport(), user.getNodeIp(), (short) user.getNodePort(), user.getLinetype(), user.getUsername(), CLIENT_VERSION, user.getPrivateIp(), user.getPublicIp(), user.getBrowsable(), user.getUploads(), user.getMaxUploads(), user.getQueued(), user.getAge(), user.getGender(), user.getCountry(), user.getRegion());
            send(pkg);
            updateTimer.startTimer();
        }
        catch(SocketTimeoutException ex)
        {

        }

    }

    public void send(HPackage pkg) {
        try {
            socket.write(HPackageSerializer.getInstance().getBytes(pkg));
        } catch (IOException ex) {
            System.err.println(ex.getMessage());
        }

    }
    
    @Override
    public void run() {

    }
}

I want to start the method conectar (). But using AsynTask would be terrible because I must to put all methods in another class and there would be a conflict. It wouldn't work, I think.... How can I do this? Thanks


Solution

  • If you need todo a simple work in background do not use deprecated AsyncTask use Executors.

            Executor executor = Executors.newSingleThreadExecutor();
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    // run your background code here
                }
            });