如何正确使用 AsyncTask? [关闭]

Posted

技术标签:

【中文标题】如何正确使用 AsyncTask? [关闭]【英文标题】:How to use AsyncTask correctly? [closed] 【发布时间】:2021-02-15 15:36:03 【问题描述】:

这种情况下如何正确使用Asynctask? 因此,在某些应用程序中,我遇到了异常:“android.os.NetworkOnMainThreadException”

解决它的一种方法是使用 Asynctask

但是在这种情况下如何使用它呢?

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[]  "lets.think.android@gmail.com" );
            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() 

    

我想启动方法conectar()。但是使用 AsynTask 会很糟糕,因为我必须将所有方法放在另一个类中,并且会发生冲突。我认为这行不通。我该怎么做?谢谢

【问题讨论】:

【参考方案1】:

如果您需要在后台进行简单的工作,请不要使用已弃用的AsyncTask,请使用Executors

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

【讨论】:

以上是关于如何正确使用 AsyncTask? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

AsyncTask总结

AsyncTask 完成后关闭 Activity 并返回父 Activity

应用程序关闭后后台进程(AsyncTask)仍在运行

如何在Android中强制停止AsyncTask [重复]

Android中的线程状态 - AsyncTask详解

Android -- 关闭AsyncTask(异步任务)