我想从我的本地服务器使用手机下载视频并将其保存在SD卡上,但是Android客户端崩溃,我需要一些帮助。我使用了这段代码http://www.rgagnon.com/javadetails/java-0542.html
这是服务器代码:
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public final static int SOCKET_PORT = 13267; // you may change this
public final static String FILE_TO_SEND = "d:/sintel.mp4"; // you may change this
public static void main (String [] args ) throws IOException {
FileInputStream fis = null;
BufferedInputStream bis = null;
OutputStream os = null;
ServerSocket servsock = null;
Socket sock = null;
try {
servsock = new ServerSocket(SOCKET_PORT);
while (true) {
System.out.println("Waiting...");
try {
sock = servsock.accept();
System.out.println("Accepted connection : " + sock);
// send file
File myFile = new File (FILE_TO_SEND);
byte [] mybytearray = new byte [(int)myFile.length()];
fis = new FileInputStream(myFile);
bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
os = sock.getOutputStream();
System.out.println("Sending " + FILE_TO_SEND + "(" + mybytearray.length + " bytes)");
os.write(mybytearray,0,mybytearray.length);
os.flush();
System.out.println("Done.");
}
finally {
if (bis != null) bis.close();
if (os != null) os.close();
if (sock!=null) sock.close();
}
}
}
finally {
if (servsock != null) servsock.close();
}
}
}
客户代码:
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
public class MainActivity extends ActionBarActivity {
public final static int SOCKET_PORT = 13267; // you may change this
public final static String SERVER = "127.0.0.1"; // localhost
public final static String FILE_TO_RECEIVED = "/storage/external_SD/sintel.mp4";; // you may change this, I give a
// different name because i don't want to
// overwrite the one used by server...
public final static int FILE_SIZE = 14000000; // file size temporary hard coded
// should bigger than the file to be downloaded
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void buttonClicked(View view)throws IOException{
int bytesRead;
int current = 0;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
Socket sock = null;
try {
sock = new Socket(SERVER, SOCKET_PORT);
System.out.println("Connecting...");
// receive file
byte [] mybytearray = new byte [FILE_SIZE];
InputStream is = sock.getInputStream();
fos = new FileOutputStream(FILE_TO_RECEIVED);
bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray, 0 , current);
bos.flush();
// System.out.println("File " + FILE_TO_RECEIVED
// + " downloaded (" + current + " bytes read)");
}
finally {
if (fos != null) fos.close();
if (bos != null) bos.close();
if (sock != null) sock.close();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
的xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="download video"
android:id="@+id/bdownload"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="199dp"
android:onClick="buttonClicked"
android:nestedScrollingEnabled="false" />
</RelativeLayout>
和清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.aidan.client" >
<uses-permission android:name="android.permission.INTERNET" >
</uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
答案 0 :(得分:1)
您正在UI thread
中执行大量网络任务,导致您的应用崩溃....
将您的buttonClicked
代码放在后台主题
public void buttonClicked(View view)throws IOException{
new Thread(new Runnable() {
@Override
public void run() {
int bytesRead;
int current = 0;
FileOutputStream fos = null;
BufferedOutputStream bos = null;
Socket sock = null;
try {
sock = new Socket(SERVER, SOCKET_PORT);
System.out.println("Connecting...");
// receive file
byte [] mybytearray = new byte [FILE_SIZE];
InputStream is = sock.getInputStream();
fos = new FileOutputStream(FILE_TO_RECEIVED);
bos = new BufferedOutputStream(fos);
bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead =
is.read(mybytearray, current, (mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray, 0 , current);
bos.flush();
// System.out.println("File " + FILE_TO_RECEIVED
// + " downloaded (" + current + " bytes read)");
}
finally {
if (fos != null) fos.close();
if (bos != null) bos.close();
if (sock != null) sock.close();
}
}
}).start();
}
答案 1 :(得分:0)
您可以使用Android自己的DownloadManager安装程序来提供自己的实现。
它还将为您提供导航抽屉的进度,这将消除您的大量头痛。